Python:__ slots__及其描述符的用法

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'
上一篇:redis入门(三)(转载)


下一篇:redis-5.0.5 集群部署