在python中传递静态方法

时间:2017-03-24 16:05:16

标签: python static-methods

您能解释为什么以下代码段不起作用吗?

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中的行为是相同的。

2 个答案:

答案 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