Python 运算符'的非常奇怪的行为;是';用方法

Python 运算符'的非常奇怪的行为;是';用方法,python,python-2.7,methods,python-internals,Python,Python 2.7,Methods,Python Internals,为什么第一个结果为False,而不是为True >>> from collections import OrderedDict >>> OrderedDict.__repr__ is OrderedDict.__repr__ False >>> dict.__repr__ is dict.__repr__ True 这两个OrderedDict.\u_repr\u_未绑定到同一个对象。如果您尝试: OrderedDict.__repr__

为什么第一个结果
为False
,而不是
为True

>>> from collections import OrderedDict
>>> OrderedDict.__repr__ is OrderedDict.__repr__
False
>>> dict.__repr__ is dict.__repr__
True

这两个
OrderedDict.\u_repr\u_
未绑定到同一个对象。如果您尝试:

 OrderedDict.__repr__ == OrderedDict.__repr__

您将看到它们具有相同的值。

对于用户定义的函数,在Python 2中,通过
OrderedDict._repr__
就是这样一个方法对象,因为包装函数是作为一个对象实现的

描述符协议将在支持它的对象上调用,因此无论何时尝试访问
OrderedDict.\uuuuu repr\uuuu.\uuuu get\uuuu()
,都会调用
;对于类
None
(无实例)和类对象本身传递。因为每次调用函数
\uuuu get\uuuu
方法时都会得到一个新的方法对象,
会失败。它不是同一个方法对象

dict.\uuuuu repr\uuuuu
不是一个自定义Python函数,而是一个C函数及其
\uuuu get\uuuu
描述符方法。每次访问该属性都会给您提供相同的对象,因此
is
工作:

>>> dict.__repr__.__get__(None, dict) is dict.__repr__  # None means no instance
True
方法具有引用包装函数的
\uuu func\uu
属性,请使用该属性测试标识:

>>> OrderedDict.__repr__
<unbound method OrderedDict.__repr__>
>>> OrderedDict.__repr__.__func__
<function __repr__ at 0x102c2f1b8>
>>> OrderedDict.__repr__.__func__.__get__(None, OrderedDict)
<unbound method OrderedDict.__repr__>
>>> OrderedDict.__repr__.__func__ is OrderedDict.__repr__.__func__
True
>>OrderedDict.\uuu报告__
>>>订购信息和报告功能__
>>>OrderedDict.\uuuuuu repr\uuuuuuu.\uuuuu func\uuuuuuuuuu获取(无,OrderedDict)
>>>已订购信息。已订购信息。已订购信息。已订购信息。已订购信息。已订购信息。已订购信息__
真的

Python3取消了未绑定的方法,
function.\uuu get\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。但是您将看到绑定方法的相同行为,即从实例检索的方法。

Python3.3返回True@JustinEngel:这是因为Python 3取消了未绑定的方法,所有方法都是绑定的。在Python 3中尝试
OrderedDict()。\uuuu repr\uuuuu是OrderedDict()。\uuuu repr\uuuuu
,您将看到相同的行为。我很好奇在实际应用中如何涉及到类似的内容code@NickT:验证猴子修补的方法需要了解如何绑定方法。将一个类中的方法添加到另一个类中还需要提取函数对象,而不是方法等。作为一个简单的测试,您可以自己证明这一点,创建一个类,将其
\uuuuuu repr\uuu
方法作为
\uuuu repr\uuu=lambda:x
,而
is
测试将失败。实际上,通常重写
\uuuu repr\uuuu
会导致
is
失败。而且,在一般情况下,没有类的纯python未绑定方法可以与
True
is
相比:您可以创建(多个)对方法对象的引用,然后仍然可以使用
is
。但是从类中检索一个方法会给你一个新的对象,因为函数
\uuuu get\uuuu
方法会产生一个新的对象。啊,是的,当然,我的意思是像OP一样通过直接比较。很明显,你的答案实际上是这么说的,只是不是很明显。也许提供一个简单的例子,说明对于任何带有纯python方法的类,这种情况都会发生,这对这个问题的未来读者会有所帮助。@Aruistante:我在这里更关注的是与dict的区别;实际上,仅仅谈论方法对象是重复的。