'classmethod'对象不可调用

use*_*425 21 python class-method

好的,我有这个代码:

class SomeClass:
    @classmethod
    def func1(cls,arg1):
        #---Do Something---
    @classmethod
    def func2(cls,arg1):
        #---Do Something---

    # A 'function map' that has function name as its keys and the above function
    # objects as values
    func_map={'func1':func1,'func2':func2}

    @classmethod
    def func3(cls,arg1):
        # following is a dict(created by reading a config file) that
        # contains func names as keys and boolean as values that tells
        # the program whether or not to run that function
        global funcList
        for func in funcList:
            if funcList[func]==True:
                cls.func_map[func](arg1)        #TROUBLING PART!!!

    if _name__='main'
        SomeClass.func3('Argumentus-Primus')
Run Code Online (Sandbox Code Playgroud)

当我运行这个时,我不断收到错误:

Exception TypeError: "'classmethod' object is not callable"

我无法弄清楚这有什么不对,感谢您的帮助.

Hug*_*ell 16

在定义类之前,您无法创建对classmethods的引用.你必须将它移出类定义.但是,使用全局函数映射来确定运行的内容真的很尴尬.如果你描述了你想要做的事情,我们可能会建议一个更好的解决方案.

class SomeClass(object):
    @classmethod
    def func1(cls, arg1):
        print("Called func1({})".format(arg1))

    @classmethod
    def func2(cls, arg1):
        print("Call func2({})".format(arg1))

    @classmethod
    def func3(cls, arg1):
        for fnName,do in funcList.iteritems():
            if do:
                try:
                    cls.func_map[fnName](arg1)
                except KeyError:
                    print("Don't know function '{}'".format(fnName))

# can't create function map until class has been created
SomeClass.func_map = {
    'func1': SomeClass.func1,
    'func2': SomeClass.func2
}

if __name__=='__main__':
    funcList = {'func1':True, 'func2':False}
    SomeClass.func3('Argumentus-Primus')
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你的回复.这对我来说真的很困惑.当我在dict中为他们辩护时,为什么python不会阻止我在那个地方?它只是在我试图打电话时抱怨.2.这个全局funcList是通过读取配置文件创建的(读取配置是在不同的模块中完成的),所以我想不出另一种方式...... 3.我试图从用户那里获取输入配置文件这将告诉程序运行什么函数,同时这样做是为了保持代码的不同部分之间的清晰分离(以便使其易于扩展) (2认同)

kev*_*rpe 10

我今晚发现了一些有用的东西:我们可以通过以下方式解开魔法staticmethodclassmethod物体:getattr(func, '__func__')

我是如何找到这些信息的?使用JetBrains的PyCharm(我不知道其他Python IDE),我查看了@staticmethod和的源代码@classmethod.两个类都定义了属性__func__.

"其余部分留给读者练习."

  • 可以直接使用 func.__func__ ,不需要 getattr(func, '__func__')` (3认同)
  • 这些只是为pycharm创建的存根,因此代码完成和内省工作.实际上,那些装饰器是用C语言编写的内置函数 (2认同)

les*_*nik 5

所有其他答案都建议在定义之外添加一些代码class SomeClass。在某些情况下可能没问题,但就我而言却非常不方便。我真的很想把它留func_map在课堂上。

我建议采用以下方法。不使用类变量,而是使用另一种类方法:

class SomeClass:
    # ...

    @classmethod
    def get_func_map(cls):
        return {'func1': cls.func1, 'func2': cls.func2}

    @classmethod
    def func3(cls, arg1):
        # .....
        cls.get_func_map()[func_name](arg1)
Run Code Online (Sandbox Code Playgroud)

当然,您应该修改此代码,以便每次调用该get_func_map方法时都不会构造新的字典。这很简单,我自己并没有这样做,以保持示例小而清晰。

在 python 3.6 上测试