问题描述
如果我有
class A:
def foo(self):
pass
这计算为True
:
getattr(A, 'foo') is A.foo
但这计算为False
:
a = A()
getattr(a, 'foo') is a.foo
就像
a.foo is a.foo
为什么?
我发现getattr(a, 'foo')
和a.foo
都由
<bound method A.foo of <__main__.A object at 0x7a2c4de10d50>>)
所以那里没有任何提示....
至少在CPython中,绑定方法被实现为类method
的实例.每次您请求绑定函数的值时,都会得到该类的 new 实例.
x = a.foo
y = a.foo
assert x is not y
id(x) # E.g. 139664144271304
id(y) # E.g. 139664144033992
type(x) # <class 'method'>
type(y) # <class 'method'>
该类所做的全部工作是存储对实例和 unbound 函数的引用,当您调用该类时,它将与存储的实例(以及您的其他参数)一起调用unbound函数. /p>
像A.foo
一样,未绑定函数只是常规的旧函数-没有构造新的代理类实例,因此身份可以按您期望的方式工作.
产生这种差异的原因是a.foo
的语义取决于两件事,即a
的值和A.foo
的值.为了能够在以后的任何时间点获得此含义,这两个值都需要存储.这是method
类的作用.
相反,A.foo
的含义仅取决于单个值:A.foo
.因此,不需要任何额外的工作来存储任何东西,并且使用值本身.
您可能会考虑预分配绑定方法实例的想法,以便a.foo
总是返回相同的不可变对象-但考虑到Python的动态特性,每次构造一个新对象都是更简单和便宜的,即使它们可以相同.
If I have a
class A:
def foo(self):
pass
this evaluates to True
:
getattr(A, 'foo') is A.foo
but this evaluates to False
:
a = A()
getattr(a, 'foo') is a.foo
as does
a.foo is a.foo
Why?
I found that getattr(a, 'foo')
and a.foo
both are represented by
<bound method A.foo of <__main__.A object at 0x7a2c4de10d50>>)
So no hint there....
At least in CPython, bound methods are implemented as an instance of a class method
. Every time you ask for the value of a bound function, you get a new instance of this class.
x = a.foo
y = a.foo
assert x is not y
id(x) # E.g. 139664144271304
id(y) # E.g. 139664144033992
type(x) # <class 'method'>
type(y) # <class 'method'>
All this class does is store a reference to the instance and the unbound function, and when you call the class it calls the unbound function with the stored instance (along with your other arguments).
Unbound functions, like A.foo
, are just regular old functions - no new instances of proxy classes are being constructed, so identity works as you expect.
The reason for this difference is that the semantic meaning of a.foo
depends on two things, the value of a
and the value of A.foo
. In order to be able to get this meaning at any point in time later, both of these values need to be stored. This is what the method
class does.
Conversely, the meaning of A.foo
depends only on a single value: A.foo
. So no additional work is required to store anything, and the value itself is used.
You might consider the idea of pre-allocating bound method instances, so that a.foo
always returns the same immutable object - but given the dynamic nature of Python, it is simpler and cheaper to just construct a new one each time, even if they could be the same.
这篇关于为什么`instance_of_object.foo被instance_of_object.foo`评估为False?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!