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的区别;实际上,仅仅谈论方法对象是重复的。