3
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 文档__slots__实现:

__slots__通过为每个变量名创建描述符(实现描述符)在类级别实现。因此,类属性不能用于设置由__slots__;定义的实例变量的默认值。否则,类属性将覆盖描述符分配。

但是描述符可以处理继承(至少如果用纯 python 编写的话)。

有谁知道,为什么这不起作用__slots__

编辑:似乎描述符通常不适用于super(),如果您正在尝试编写(虽然可以阅读)。所以我的问题宁愿是:为什么描述符是只读的,如果用 调用super()

4

1 回答 1

4

super()不返回描述符,它返回获取描述符的结果。它也不返回函数,它返回绑定方法;函数也充当描述符,它们的方法返回一个方法。.__get__()

因为实例上没有a定义,所以没有值,描述符引发 AttributeError。.__get__()

如果您a在以下实例上定义,则一切正常Foo

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()可以找到描述符的结果就好了(使用不同的属性名称演示而不是 clobber self.a):

>>> class Bar(Foo):
...     __slots__ = ('b',)
...     @property
...     def b(self):
...         return super(Bar, self).a
... 
>>> Bar().a
'spam'
于 2013-01-09T21:16:34.353 回答