您能解释为什么以下代码段不起作用吗?
class A:
@staticmethod
def f():
print('A.f')
dict = {'f': f}
def callMe(g):
g()
callMe(A.dict['f'])
产生
TypeError: 'staticmethod' object is not callable
有意思地,将其改为
class A:
@staticmethod
def f():
print('A.f')
dict = {'f': f}
def callMe(g):
g()
callMe(A.f)
或
class A:
@staticmethod
def f():
print('A.f')
dict = {'f': lambda: A.f()}
def callMe(g):
g()
callMe(A.dict['f'])
给出预期结果
A.f
据我所知,Python 2和3中的行为是相同的。
答案 0 :(得分:3)
f
内的A
对象是descriptor,而不是静态方法本身 - 当使用A实例调用时,返回静态方法;阅读链接,并查找"描述符协议"有关其工作原理的更多信息。方法本身存储为描述符的__func__
属性。
你可以自己看看:
>>> A.f
<function A.f at 0x7fa8acc7ca60>
>>> A.__dict__['f']
<staticmethod object at 0x7fa8acc990b8>
>>> A.__dict__['f'].__func__ # The stored method
<function A.f at 0x7fa8acc7ca60>
>>> A.__dict__['f'].__get__(A) # This is (kinda) what happens when you run A.f
<function A.f at 0x7fa8acc7ca60>
另请注意,您可以使用A.__dict__
访问f
描述符对象,而不需要创建自己的字典来存储它。
答案 1 :(得分:1)
staticmethod对象是descriptor,您需要将其作为(类的)属性访问,以使描述符机制生效。 staticmethod对象本身不可调用,但其__get__
的结果是可调用的。另请参阅this Python bug discussion。