Python “静态方法”对象不可调用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/41921255/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 01:53:13  来源:igfitidea点击:

'staticmethod' object is not callable

python

提问by Ramin Farajpour Cami

I have this code:

我有这个代码:

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

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

obj = A.switch[1]()

When I run this I keep getting the error:

当我运行它时,我不断收到错误消息:

TypeError: 'staticmethod' object is not callable

how to resolve it?

如何解决?

回答by Martijn Pieters

You are storing unboundstaticmethodobjects in a dictionary. Such objects (as well as classmethodobjects, functions and propertyobjects) are only bound through the descriptor protocol, by accessing the name as an attribute on the class or an instance. Directly accessing the staticmethodobjects in the class body is not an attribute access.

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

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

创建类之后创建字典(因此您可以将它们作为属性访问),或者显式绑定,或者在将它们存储到字典之前提取原始函数。

Note that 'binding' for staticmethodobjects merely means that the context is merely ignored; a bound staticmethodreturns the underlying function unchanged.

请注意,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,   
}

or to bind explicitly, passing in a dummy context (which will be ignored anyway):

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

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

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

or access the underlying function directly with the __func__attribute:

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

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

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

However, if all you are trying to do is provide a namespacefor a bunch of functions, then you should not use a class object in the first place. Put the functions in a module. That way you don't have to use staticmethoddecorators in the first place and don't have to unwrap them again.

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