Python documentation about the is
operator说:
The operators
is
andis not
test for object identity:x is y
is true if and only ifx
andy
are the same object.x is not y
yields the inverse truth value.
让我们试试看:
>>> def m():
... pass
...
>>> m is m
True
Python documentation also says :
Due to automatic garbage-collection, free lists, and the dynamic nature of descriptors, you may notice seemingly unusual behaviour in certain uses of the
is
operator, like those involving comparisons between instance methods, or constants. Check their documentation for more info.
>>> class C:
... def m():
... pass
...
>>> C.m is C.m
False
我搜索了更多解释,但找不到任何解释。
为什么 C.m 是 C.m
错误?
我正在使用 Python 2.x。如以下答案中所述,在 Python 3.x 中,C.m is C.m
为真。
最佳答案
当您请求作为函数的实例的属性时,您会得到一个绑定(bind)方法:一个可调用对象,它包装类中定义的函数并将该实例作为第一个参数传递。在 Python 2.x 中,当您请求类的一个函数属性时,您会得到一个类似的代理对象,称为未绑定(bind)方法:
>>> class A: m = lambda: None
...
>>> A.m
<unbound method A.<lambda>>
这个特殊对象是在您请求时创建的,显然没有缓存在任何地方。这意味着当你这样做时
>>> A.m is A.m
False
您正在创建两个不同 未绑定(bind)方法对象并测试它们的身份。
注意
>>> x = A.m
>>> x is x
True
和
>>> A.m.im_func is A.m.im_func
True
工作正常。 (im_func
是未绑定(bind)方法对象包装的原始函数。)
顺便说一下,在 Python 3.x 中,C.m is C.m
是 True,因为(有点无意义的)未绑定(bind)方法代理对象被完全删除,您只得到您定义的原始函数。
这只是 Python 中属性查找的动态特性的一个示例:当您请求对象的属性时,可以运行任意 Python 来计算该属性的值。这是您的测试失败的另一个示例,其中更清楚原因:
>>> class ChangingAttribute(object):
... @property
... def n(self):
... self._n += 1
... return self._n
...
... def __init__(self):
... self._n = 0
...
>>> foo = ChangingAttribute()
>>> foo.n
1
>>> foo.n
2
>>> foo.n
3
>>> foo.n is foo.n
False
>>> foo.n
6
关于python - 为什么方法与自身不相同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4639908/