“ staticmethod”对象不可调用

我有这个密码:

class A(object):
@staticmethod
def open():
return 123


@staticmethod
def proccess():
return 456


switch = {
1: open,
2: proccess,
}




obj = A.switch[1]()

当我运行这个命令时,我不断得到错误:

TypeError: 'staticmethod' object is not callable

怎么解决呢?

62607 次浏览

您正在字典中存储 不受约束 staticmethod对象。这样的对象(以及 classmethod对象、函数和 property对象)只能通过 描述符协议绑定,方法是将名称作为类或实例的属性访问。直接访问类主体中的 staticmethod对象不是属性访问。

Either create the dictionary after creating the class (so you access them as attributes), or bind explicitly, or extract the original function before storing them in the dictionary.

注意,staticmethod对象的“绑定”仅仅意味着上下文被忽略; 绑定的 staticmethod返回的底层函数没有改变。

So your options are to unindent the dictionary and trigger the descriptor protocol by using attributes:

class A(object):
@staticmethod
def open():
return 123
@staticmethod
def proccess():
return 456


A.switch = {
1: A.open,
2: A.proccess,
}

或者显式绑定,传递一个虚拟上下文(无论如何都会被忽略) :

class A(object):
@staticmethod
def open():
return 123
@staticmethod
def proccess():
return 456


switch = {
1: open.__get__(object),
2: proccess.__get__(object),
}

或直接使用 __func__属性访问底层函数:

class A(object):
@staticmethod
def open():
return 123
@staticmethod
def proccess():
return 456


switch = {
1: open.__func__,
2: proccess.__func__,
}

但是,如果您所要做的只是为一堆函数提供一个 命名空间,那么您首先就不应该使用类对象。将函数放在 模组中。这样,您就不必在第一时间使用 staticmethod装饰器,也不必再次拆开它们。

除了 Pieters 的回答,你还可以去掉 @staticmethod:

class A(object):
def open():
return 123


def proccess():
return 456


switch = {
1: open,
2: proccess,
}


obj = A.switch[1]()

然而,这样就不可能用 self调用 openprocess

  • 在类之外,可以使用 A.open()A.process()调用它们,就像常见的静态方法一样。
  • 在类内部,它们只能用 open()process()调用,没有 A.,
    • A.open将会失败。(我只用装饰器使用来测试这个案例。(@open))
    • 而且,它们必须放在调用它们的函数之前。
class A(object):
def open():
return 123


def proccess():
return 456


switch = {
1: lambda : A.open(),
2: lambda : A.proccess(),
}