为什么方法没有参考平等?

我有一个错误,我使用的方法是相互依赖的。 事实certificate情况并非如此:

 >>> class What(object): def meth(self): pass >>> What.meth is What.meth False >>> inst = What() >>> inst.meth is inst.meth False 

为什么是这样? 它适用于常规function:

 >>> def func(): pass >>> func is func True 

每次访问方法对象都会被创build。 函数作为描述符 ,在调用.__get__方法时返回一个方法对象:

 >>> What.__dict__['meth'] <function meth at 0x10a6f9c80> >>> What.__dict__['meth'].__get__(None, What) <unbound method What.meth> >>> What.__dict__['meth'].__get__(What(), What) <bound method What.meth of <__main__.What object at 0x10a6f7b10>> 

改用==相等性testing。

如果.im_self.im_func属性相同,则两个方法相等。 如果您需要testing这些方法表示相同的底层函数 ,请testing它们的im_func属性:

 >>> What.meth == What.meth # unbound methods (or functions in Python 3) True >>> What().meth == What.meth # unbound method and bound method False >>> What().meth == What().meth # bound methods with *different* instances False >>> What().meth.im_func == What().meth.im_func # functions True 

Martijn是正确的,一个新的方法是由.__get__生成的对象,所以他们的地址指针不等于一个评估。 请注意,使用==将在Python 2.7中按照预期进行评估。

 Python2.7 class Test(object): def tmethod(self): pass >>> Test.meth is Test.meth False >>> Test.meth == Test.meth True >>> t = Test() >>> t.meth is t.meth False >>> t.meth == t.meth True 

但是请注意,从实例引用的方法不等同于从类引用的那些方法,因为自实例引用了自引用。

 >>> t = Test() >>> t.meth is Test.meth False >>> t.meth == Test.meth False 

在Python 3.3中,方法的is运算符通常与==相同,所以在本例中您将获得预期的行为。 这是由Python 3中的__cmp__消失和清洁的方法对象表示造成的; 方法现在有__eq__ ,引用不是内build的对象,所以行为遵循的是没有Python 2的期望。

 Python3.3 >>> Test.meth is Test.meth True >>> Test.meth == Test.meth True >>> Test.meth.__eq__(Test.meth) True