gpt4 book ai didi

python - python解释器如何决定何时调用 __set__ 和 __get__ 方法,何时不调用?

转载 作者:太空宇宙 更新时间:2023-11-03 14:44:45 25 4
gpt4 key购买 nike

假设我们定义以下Python描述符

class FooDescriptor():
def __init__(self, name='foo', initval='initval'):
self.name = name
self.val = initval

def __get__(self, instance, cls):
print("invoke get {} in instance {} in class {}".format(self.name, instance, cls))
return self.val

def __set__(self, instance, val):
print("invoke set {} in instance {}".format(self.name, instance))
self.val = val

现在如果我们定义类 Foo具有 FooDescriptor 类型的类属性以及相同类型的实例属性:

class Foo():
cdescr = FooDescriptor(name='class attribute descr', initval=1)
def __init__(self):
self.idescr = FooDescriptor(name='instance attribute descr', initval=2)

我们获得了类描述符所需的行为:

>>> foo = Foo()
>>> foo.cdescr
invoke get class attribute descr in instance <__main__.Foo object at 0x10189ecc0> in class <class '__main__.Foo'>
1
>>> foo.cdescr = 100
invoke set class attribute descr in instance <__main__.Foo object at 0x10189ecc0>
>>> foo.cdescr
invoke get class attribute descr in instance <__main__.Foo object at 0x10189ecc0> in class <class '__main__.Foo'>
100

但是对于实例属性 idescr ,描述符对象的__set____get__访问或设置属性时不会调用方法:

>>> foo.idescr
<__main__.FooDescriptor object at 0x10189ecf8>
>>> foo.idescr = 120
>>> foo.idescr
120
>>> type(foo.idescr)
<class 'int'>

为了更好地理解描述符的范围以及 python 如何决定调用它们的任何答案 __set____get__当属性协议(protocol) .被看到将不胜感激。

最佳答案

这是因为在查找实例类的属性时使用描述符。如果它是一个实例属性,它将不会干扰描述符协议(protocol)。

解决此类问题的一个很好的资源是 ionel 关于元类的博客,其中包含此图像,该图像还显示了何时使用描述符:

enter image description here

(图片复制自 here )

因为 cdescr 位于 class.__dict__ 中并且具有 __get____set__ 它将返回描述符的内容__get__ 返回。但是,由于 idescr 不在 class.__dict__ 中,因此它只会返回存储在 instance.__dict__ 中的内容。

关于python - python解释器如何决定何时调用 __set__ 和 __get__ 方法,何时不调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46329372/

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