描述符和直接访问:Python参考
它告诉我应该可以直接访问属性描述符,尽管我怀疑它的语法描述符和直接访问:Python参考,python,descriptor,python-descriptors,Python,Descriptor,Python Descriptors,它告诉我应该可以直接访问属性描述符,尽管我怀疑它的语法x.\uuu get\uu(a)。但我下面构建的示例失败了。我错过什么了吗 class MyDescriptor(object): """Descriptor""" def __get__(self, instance, owner): print "hello" return 42 class Owner(object): x = MyDescriptor() def do_
x.\uuu get\uu(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)中遇到的错误。这个错误消息对我来说是有意义的,但文档中似乎没有说明它是如何工作的
Traceback (most recent call last):
File "descriptor_test.py", line 15, in <module>
my_instance.do_direct_access()
File "descriptor_test.py", line 10, in do_direct_access
self.x.__get__(self)
AttributeError: 'int' object has no attribute '__get__'
shell returned 1
回溯(最近一次呼叫最后一次):
文件“descriptor_test.py”,第15行,在
my_实例。do_direct_access()
do_direct_access中第10行的文件“descriptor_test.py”
self.x.\uuuuu获取\uuuuuu(self)
AttributeError:“int”对象没有属性“\uuuu get\uuuu”
壳返回1
通过访问您已调用的\uuuu get\uuuu
上的描述符。正在返回值42
对于任何属性访问,Python都会查看对象的类型(因此这里是type(self)
),以查看是否存在描述符对象(例如,具有。\uuuuuu get\uuuuu()
方法的对象),然后调用该描述符
这就是方法的工作原理;找到一个函数对象,它有一个。\uuuu get\uuuu()
方法,该方法被调用并返回一个绑定到self的方法对象
如果你想直接访问描述符,你必须绕过这个机制;访问所有者的词典中的x
:
>>> Owner.__dict__['x']
<__main__.MyDescriptor object at 0x100e48e10>
>>> Owner.__dict__['x'].__get__(None, Owner)
hello
42
所有者
>>>所有者.uuu dict_uuuu['x'].uuuu get_uuuu(无,所有者)
你好
42
此行为记录在您看到的x.\uuu get\uuu(a)
直接调用的正上方:
属性访问的默认行为是从对象的字典中获取、设置或删除属性。例如,a.x
有一个查找链,从a.\uuuu dict\uuuuuuu['x']
开始,然后是type(a).\uuuu dict\uuuu['x']
,然后是type(a)
的基类,不包括元类
文档中的直接调用场景仅适用于直接引用描述符对象(未调用)的情况;Owner.\uu dict\uu['x']
表达式就是这样一个引用
另一方面,您的代码是实例绑定场景的一个示例:
实例绑定
如果绑定到对象实例,a.x
将转换为调用:type(a)。\uuuu dict\uuu['x']。\uuuu get\uuu(a,type(a))
对,我明白了。但是文档中有我使用的精确代码。那么文档有错吗?@gkb0986:文档中没有提到x
是一个实例。我想是的。“”“直接调用最简单也是最不常见的调用是当用户代码直接调用描述符方法时:x.。\uuu get\uuuu(a)。”“但是我可能没有正确地解析它。@gkb0986文档没有错。在该代码段中,x
是描述符对象的名称self.x
不计算描述符对象的属性访问,因此按照本文和文档中第二个代码段所示的方式进行处理。@gkb0986:在此基础上展开;只有当您实际有对描述符本身的引用时,才能进行直接调用;从self
python调用实例绑定场景,您无法访问描述符,因为python已经为您调用了它。