Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python解释器如何决定何时调用_uset和_uget方法,何时不调用?_Python - Fatal编程技术网

python解释器如何决定何时调用_uset和_uget方法,何时不调用?

python解释器如何决定何时调用_uset和_uget方法,何时不调用?,python,Python,假设我们定义以下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

假设我们定义以下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
现在,如果我们将class
Foo
定义为具有类型为
FooDescriptor
的class属性和相同类型的实例属性:

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

如果能够更好地理解描述符的范围,以及python在看到属性protocal
时决定如何调用它们的
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
将不胜感激。

这是因为在查找实例类的属性时会使用描述符。如果它是一个实例属性,那么它就不需要使用描述符协议

这类问题的一个很好的来源是ionel关于元类的博客,其中包含了这样一个图像,该图像还显示了使用描述符的时间:

(图像复制自)


因为
cdescr
类中,并且具有
\uuuu get\uuuu
\uuu set\uuuuu
它将返回描述符
\uu get\uuuuu>返回的内容。但是,因为
idescr
不在
类中。它将简单地返回
实例中存储的内容。描述符协议不会对实例属性起作用。描述符是类对象的成员,而不是实例对象的成员
>>> foo.idescr
<__main__.FooDescriptor object at 0x10189ecf8>
>>> foo.idescr = 120
>>> foo.idescr
120
>>> type(foo.idescr)
<class 'int'>