class Foo(object):
__slots__ = ('a',)
class Bar(Foo):
@property
def a(self):
return super(Bar, self).a
super(Bar, Bar()).a = 4
If I’m using this code, this doesn’t work:
>>> super(Bar, Bar()).a = 4
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'super' object has no attribute 'a'
Why?
According to the python docs, __slots__ are implemented :
__slots__are implemented at the class level by creating descriptors (Implementing Descriptors) for each variable name. As a result, class
attributes cannot be used to set default values for instance variables
defined by__slots__; otherwise, the class attribute would overwrite
the descriptor assignment.
But descriptors can cope with inheritance (at least if written in pure python).
Does anyone get know, why this is not working with __slots__?
Edit: It seems like descriptors are generally not working with super(), if you’re trying to write (read works, though). So my question would rather be: Why are descriptors read-only, if invoked with super()?
super()doesn’t return the descriptor, it returns the result of getting the descriptor. It doesn’t return functions either, it returns the bound method; functions act as descriptors too, and their.__get__()method returns a method.Because there is no
adefined on the instance, there is no value and the descriptor.__get__()raises an AttributeError.Things work if you define
aon instances ofFoo:So, accessing a
__slots__descriptor without a value raises anAttributeError:but give the instance a value, and the
AttributeErrorgoes away:Now
super()can find the result of the descriptor just fine (demonstrating with a different attribute name to not clobberself.a):