鉴于课程:
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
?
答案 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中的裸函数,每次查找都会生成相同的对象。