类方法的身份

时间:2015-03-01 09:57:46

标签: python

鉴于课程:

class MyClass(object):
    @classmethod
    def my_class_method(cls):
        return None

为什么

MyClass.my_class_method is MyClass.my_class_method

评估为False,而此

id(MyClass.my_class_method) == id(MyClass.my_class_method)

True

1 个答案:

答案 0 :(得分:2)

classmethod装饰器将方法包装在描述符中。 MyClass.my_class_method与代码MyClass.__dict__['my_class_method'].__get__(None, MyClass)的功能相同; __get__为每次调用返回一个不同的绑定方法包装器,因此2是不同的对象,is失败。

id being the same is just a (common) coincidence,因为CPython中的id是根据对象所在的地址计算的;当计算第一个绑定方法包装器的id时,该包装器上的引用计数减少并且包装器被释放;通过偶然事件,第二个将被分配在完全相同的地址。 id(obj)保证仅对每个当前生活的对象都是不同的。


在Python 2中,前者适用于未绑定方法:

>>> class MyClass():   
...     def x(self):
...         pass
... 
>>> MyClass.x
<unbound method MyClass.x>
>>> MyClass.x is MyClass.x
False

在Python 3中,未绑定的方法语义已更改,现在

>>> class MyClass():   
...    def x(self):
...        pass
...
>>> MyClass.x
<function __main__.x>
>>> MyClass.x is MyClass.x
True

未绑定的实例方法是Python 3中的裸函数,每次查找都会生成相同的对象。