描述符和直接访问:Python参考 [英] Descriptors and direct access: Python reference

查看:91
本文介绍了描述符和直接访问:Python参考的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

python 3.3文档告诉我直接访问属性描述符应该是可能的,尽管我对其语法x.__get__(a)持怀疑态度.但是我在下面构造的示例失败了.我想念什么吗?

The python 3.3 documentation tells me that direct access to a property descriptor should be possible, although I'm skeptical of its syntax x.__get__(a). But the example that I constructed below fails. Am I missing something?

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()

这是我在Python 2.7(以及移植代码段后的Python 3.2)中遇到的错误.该错误消息对我来说很有意义,但这似乎不是文档所说的那样.

Here's the error I get in Python 2.7 (and also Python 3.2 after porting the snippet of code). The error message makes sense to me, but that doesn't seem to be how the documentation said it would work.

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 

推荐答案

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

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

For any attribute access, Python will look to the type of the object (so type(self) here) to see if there is a descriptor object there (an object with a .__get__() method, for example), and will then invoke that descriptor.

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

That's how methods work; a function object is found, which has a .__get__() method, which is invoked and returns a method object bound to self.

如果您想直接访问描述符,则必须绕过此机制.在Owner__dict__词典中访问x:

If you wanted to access the descriptor directly, you'd have to bypass this mechanism; access x in the __dict__ dictionary of Owner:

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

此行为记录在您直接看到x.__get__(a)直接调用的上方:

This behaviour is documented right above where you saw the x.__get__(a) direct call:

属性访问的默认行为是从对象的字典中获取,设置或删除属性.例如,a.x具有一个查找链,该查找链从a.__dict__['x']开始,然后是type(a).__dict__['x'],并一直延伸到type(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']表达式就是这样的引用.

The Direct Call scenario in the documentation only applies when you have a direct reference to the descriptor object (not invoked); the Owner.__dict__['x'] expression is such a reference.

您的代码是实例绑定方案的示例:

Your code on the other hand, is an example of the Instance Binding scenario:

实例绑定
如果绑定到对象实例,则将a.x转换为调用:type(a).__dict__['x'].__get__(a, type(a)).

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

这篇关于描述符和直接访问:Python参考的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆