试图调用类方法的代码中的各种错误

2024-05-16 18:09:55 发布

您现在位置:Python中文网/ 问答频道 /正文

我有这个密码:

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')

当我运行此程序时,我会不断收到错误消息:

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

我不知道这是怎么回事,希望你能帮助我。


Tags: mapthatdefasfunctiondosomethingcls
3条回答

所有其他答案都建议在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)

当然,您应该修改此代码,以便在每次调用get_func_map方法时都不会构造新字典。很简单,我并不是为了保持这个例子的简洁明了。

在Python3.6上测试

今晚我发现了一些有用的东西:我们可以通过:getattr(func, '__func__')打开魔法staticmethodclassmethod对象

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

“剩下的部分留给读者作为练习。”

在定义类之前,不能创建对类方法的引用。你必须把它移出类定义。然而,使用全局函数映射来决定运行什么是非常困难的。如果你描述了你想用它做什么,我们可能会建议一个更好的解决方案。

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')

相关问题 更多 >