Say I have a class which defines __slots__
:
class Foo(object):
__slots__ = ['x']
def __init__(self, x=1):
self.x = x
# will the following work?
def __setattr__(self, key, value):
if key == 'x':
object.__setattr__(self, name, -value) # Haha - let's set to minus x
Can I define __setattr__()
for it?
Since Foo
has no __dict__
, what will it update?
All your code does, apart from negate the value, is call the parent class
__setattr__
, which is exactly what would happen without your__setattr__
method. So the short answer is: Sure you can define a__setattr__
.What you cannot do is redefine
__setattr__
to useself.__dict__
, because instances of a class with slots do not have a__dict__
attribute. But such instances do have aself.x
attribute, it's contents are just not stored in a dictionary on the instance.Instead, slot values are stored in the same location a
__dict__
instance dictionary would otherwise be stored; on the object heap. Space is reserved forlen(__slots__)
references, and descriptors on the class access these references on your behalf.So, in a
__setattr__
hook, you can just call those descriptors directly instead:Interesting detour: yes, on classes without a
__slots__
attribute, there is a descriptor that would give you access to the__dict__
object of instances:which is how normal instances can look up
self.__dict__
. Which makes you wonder where theBar.__dict__
object is found. In Python, it is turtles all the way down, you'd look that object up on thetype
object of course: