How does python interpreter decides when to invokes the __set__ and __get__ methods and when not to?
本问题已经有最佳答案,请猛点这里访问。
假设我们定义下面的python描述符
1 2 3 4 5 6 7 8 9 10 11 12 | 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 |
现在,如果我们将类
1 2 3 4 | class Foo(): cdescr = FooDescriptor(name='class attribute descr', initval=1) def __init__(self): self.idescr = FooDescriptor(name='instance attribute descr', initval=2) |
我们得到类描述符所需的行为:
1 2 3 4 5 6 7 8 9 | >>> 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 |
但是,对于实例属性
1 2 3 4 5 6 7 | >>> foo.idescr <__main__.FooDescriptor object at 0x10189ecf8> >>> foo.idescr = 120 >>> foo.idescr 120 >>> type(foo.idescr) <class 'int'> |
如果能更好地理解描述符的范围以及当属性protocal
这是因为在查找实例类的属性时使用描述符。如果它是一个实例属性,它就不会影响描述符协议。
这类问题的一个很好的来源是IONEL关于元类的博客,其中包含了这张图片,在使用描述符时也会显示:
(从此处复制的图像)
因为