gpt4 book ai didi

Python 数据模型文档 : an unbound user-defined method object and a class method object

转载 作者:太空宇宙 更新时间:2023-11-03 13:50:56 26 4
gpt4 key购买 nike

在引用资料的Data Model中,作者花了很多精力解释User-defined methods是如何创建和操作的:(参见http://docs.python.org/reference/datamodel.html#the-standard-type-hierarchy并向下滚动)

User-defined method objects may be created when getting an attribute of a class (perhaps via an in- stance of that class), if that attribute is a user-defined function object, an unbound user-defined method object, or a class method object. When the attribute is a user-defined method object, a new method object is only created if the class from which it is being retrieved is the same as, or a derived class of, the class stored in the original method object; otherwise, the original method object is used as it is.

未绑定(bind)的用户定义方法对象类方法对象有什么区别?

最佳答案

从“用户”的角度来看,Python 中的类方法是一种接收其类作为其第一个参数的方法 - 不同于接收类实例作为其第一个参数的“普通”方法 - 按照惯例是称为 self

如果你从一个类中检索一个“普通”方法,而不是从那个类的实例中检索,你会得到一个“未绑定(bind)方法”——即一个对象,它是一个函数的包装器,但它不会自动添加任何一个类本身,也不是任何实例作为调用时的第一个参数。因此,如果您要调用“未绑定(bind)方法”,您必须手动传递其类的实例作为其第一个参数。

如果你手动调用一个类的方法,另一方面,这个类被填入作为你的第一个参数:

>>> class A(object):
... def b(self):
... pass
... @classmethod
... def c(cls):
... pass
...
>>> A.b
<unbound method A.b>
>>> A.c
<bound method type.c of <class '__main__.A'>>
>>> A.c()
>>> A.b()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unbound method b() must be called with A instance as first argument (got nothing instead)
>>>

在幕后发生的事情或多或少是这样的——“新样式类”:

当定义一个类体时,方法只是普通函数——当类体结束时,Python 调用类的元类(通常是内置的 type )——并传递给它作为参数名称、基类和类主体字典。这个调用产生一个类——在 Python 中是一个对象,它是一个类,因为一切都是对象。

现在,Python 有一些自定义属性访问的巧妙方法 - 所谓的“描述符”。描述符是定义名为 __get__(或 __set____del__ 但我们在这里不关心这些)的任何对象。当访问 Python 中的类或对象的属性时,返回该属性引用的对象 - 除非它是类属性,并且对象是描述符。在这种情况下,Python 不会返回对象本身,而是对该对象调用 __get__ 方法,并返回其结果。例如,内置的 property 只是一个实现了 __set____get____del__ 的类.

现在,检索属性时发生的事情是,其主体上的任何函数(或类方法或未绑定(bind)方法,如数据模型所述)确实具有 __get__ 方法,这使得它是一个描述符。基本上,一个描述符在每次访问属性时检索命名为函数的对象,因为它在函数体上定义,围绕该函数创建一个新对象 - 一个在调用时将自动填充第一个参数的对象 - 这是也就是说,一个方法

例如:

>>> class B(object):
... def c(self):
... pass
... print c
...
<function c at 0x1927398>
>>> print B.c
<unbound method B.c>
>>> b = B()
>>> b.c
<bound method B.c of <__main__.B object at 0x1930a10>

如果你想检索函数对象,而不转换为方法对象,你可以通过类的__dict__属性来实现,它不会触发描述符:

>>> B.__dict__["c"]
<function c at 0x1927398>
>>> B.__dict__["c"].__get__
<method-wrapper '__get__' of function object at 0x1927398>
>>> B.__dict__["c"].__get__(b, B)
<bound method B.c of <__main__.B object at 0x1930a10>>
>>> B.__dict__["c"].__get__(None, B)
<unbound method B.c>

至于“类方法”,这些只是不同类型的对象,用内置的 classmethod 显式修饰 - 当它的 __get__ 被调用时它返回的对象是原始函数的包装器,它将填充 cls 作为调用时的第一个参数。

关于Python 数据模型文档 : an unbound user-defined method object and a class method object,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9090941/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com