ste*_*fen 5 python introspection
如果我有
class A:
def foo(self):
pass
Run Code Online (Sandbox Code Playgroud)
这评估为True:
getattr(A, 'foo') is A.foo
Run Code Online (Sandbox Code Playgroud)
但这评估为False:
a = A()
getattr(a, 'foo') is a.foo
Run Code Online (Sandbox Code Playgroud)
同样如此
a.foo is a.foo
Run Code Online (Sandbox Code Playgroud)
为什么?
我找到了getattr(a, 'foo'),a.foo两者都代表了
<bound method A.foo of <__main__.A object at 0x7a2c4de10d50>>)
Run Code Online (Sandbox Code Playgroud)
所以没有暗示....
至少在 CPython 中,绑定方法是作为类的实例实现的method。每次您询问绑定函数的值时,您都会获得此类的一个新实例。
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'>
Run Code Online (Sandbox Code Playgroud)
这个类所做的只是存储对实例和未绑定函数的引用,当您调用该类时,它会使用存储的实例(以及其他参数)调用未绑定函数。
未绑定函数,例如A.foo,只是常规的旧函数 - 没有构建代理类的新实例,因此身份按您的预期工作。
造成这种差异的原因是 的语义a.foo取决于两件事, 的值a和 的值A.foo。为了能够在以后的任何时间点获得这个含义,这两个值都需要存储。这就是method班级所做的。
相反, 的含义A.foo仅取决于单个值:A.foo。因此不需要额外的工作来存储任何内容,并且使用值本身。
您可能会考虑预分配绑定方法实例的想法,以便a.foo始终返回相同的不可变对象 - 但考虑到 Python 的动态性质,每次构造一个新对象会更简单、更便宜,即使它们可能是相同的。
| 归档时间: |
|
| 查看次数: |
66 次 |
| 最近记录: |