gpt4 book ai didi

Python:__slots__ 及其描述符的使用

转载 作者:太空宇宙 更新时间:2023-11-03 15:21:26 26 4
gpt4 key购买 nike

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() 不返回描述符,它返回获取描述符的结果。它也不返回函数,它返回绑定(bind)的方法;函数也充当描述符,它们的 .__get__() 方法返回一个方法。

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

如果你在 Foo 的实例上定义 a,事情就会起作用:

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'

关于Python:__slots__ 及其描述符的使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14246616/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com