描述符和直接访问:Python引用

2024-04-24 07:55:12 发布

您现在位置:Python中文网/ 问答频道 /正文

python 3.3 documentation告诉我应该可以直接访问属性描述符,尽管我对它的语法x.__get__(a)表示怀疑。但我在下面构建的例子失败了。我错过了什么?在

class MyDescriptor(object):
    """Descriptor"""
    def __get__(self, instance, owner):
        print "hello"
        return 42

class Owner(object):
    x = MyDescriptor()
    def do_direct_access(self):
        self.x.__get__(self)

if __name__ == '__main__':
    my_instance = Owner()
    print my_instance.x
    my_instance.do_direct_access()

以下是我在Python2.7(以及移植代码片段后的Python3.2)中遇到的错误。这个错误消息对我来说是有意义的,但是文档中说的似乎不是这样的。在

^{pr2}$

Tags: instanceselfgetobjectaccessmydefdocumentation
1条回答
网友
1楼 · 发布于 2024-04-24 07:55:12

通过访问self上的描述符,您已经调用了__get__。返回值42。在

对于任何属性访问,Python都会查看对象的类型(这里是type(self))以查看是否存在描述符对象(例如,具有.__get__()方法的对象),然后调用该描述符。在

方法就是这样工作的;找到一个函数对象,它有一个.__get__()方法,该方法被调用并返回一个绑定到self的方法对象。在

如果要直接访问描述符,则必须绕过此机制;访问__dict__字典中的x

>>> Owner.__dict__['x']
<__main__.MyDescriptor object at 0x100e48e10>
>>> Owner.__dict__['x'].__get__(None, Owner)
hello
42

在您看到x.__get__(a)直接调用的地方,就记录了这种行为:

The default behavior for attribute access is to get, set, or delete the attribute from an object’s dictionary. For instance, a.x has a lookup chain starting with a.__dict__['x'], then type(a).__dict__['x'], and continuing through the base classes of type(a) excluding metaclasses.

文档中的直接调用场景仅适用于直接引用描述符对象(未调用);Owner.__dict__['x']表达式就是这样一个引用。在

另一方面,您的代码是实例绑定场景的一个示例:

Instance Binding
If binding to an object instance, a.x is transformed into the call: type(a).__dict__['x'].__get__(a, type(a)).

相关问题 更多 >