class Foo(object):
__slots__ = ('a',)
class Bar(Foo):
@property
def a(self):
return super(Bar, self).a
super(Bar, Bar()).a = 4
如果我正在使用此代码,则无法使用:
>>> super(Bar, Bar()).a = 4
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'super' object has no attribute 'a'
为什么?
根据python docs,实现__slots__:
__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.
但是描述符可以应付继承(至少如果使用纯python编写).
有谁知道,为什么这不适用于__slots__?
编辑:如果您尝试编写(似乎可以读取),则描述符通常不能与super()一起使用.所以我的问题是:如果用super()调用描述符,为什么描述符是只读的?
解决方法:
super()不返回描述符,它返回获取描述符的结果.它也不返回函数,它返回绑定方法.函数也充当描述符,它们的.__ get __()方法返回一个方法.
因为实例上没有定义,所以没有值,描述符.__ get __()引发AttributeError.
如果您定义Foo的on实例,那么事情就起作用了:
class Foo(object):
__slots__ = ('a',)
def __init__(self):
self.a = 'spam'
因此,访问没有值的__slots__描述符会引发AttributeError:
>>> class Foo(object):
... __slots__ = ('a',)
...
>>> Foo.a
<member 'a' of 'Foo' objects>
>>> Foo().a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: a
>>> Foo.a.__get__(Foo(), Foo)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: a
但给实例一个值,则AttributeError消失了:
>>> class Foo(object):
... __slots__ = ('a',)
... def __init__(self):
... self.a = 'spam'
...
>>> Foo.a.__get__(Foo(), Foo)
'spam'
现在,super()可以很好地找到描述符的结果(使用不同的属性名称进行演示,不会破坏self.a):
>>> class Bar(Foo):
... __slots__ = ('b',)
... @property
... def b(self):
... return super(Bar, self).a
...
>>> Bar().a
'spam'