在试图调用classmethods代码各种错误[关闭](Various errors in code

2019-06-25 13:01发布

我有这样的代码:

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"

我无法弄清楚什么是不对的,并希望得到您的帮助。

Answer 1:

直到类已经被定义不能创建到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')


Answer 2:

我发现了一些今晚将在这里帮助:我们可以解开魔法staticmethodclassmethod通过对象: getattr(func, '__func__')

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

“剩下的就留给读者自己练习。”



Answer 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方法。 这很容易,我没有做它自己保持的例子小而清晰。

测试在蟒蛇3.6



Answer 4:

添加自己作为类中的每个方法的参数。

    if _name__='main'
    SomeClass.func3('Argumentus-Primus')

应该是这样的:

if __name__=='__main__':
    SomeClass.func3('Argumentus-Primus')

而不应该是类的体内。



Answer 5:

您可能需要尝试的静态方法。

@staticmethod
def function():...

静态方法不通过类作为一个隐含的第一个参数。



Answer 6:

这里有一个糟糕的方式做到这一点:

def func3(cls,arg1):
    global funcList
    for func in funcList:
        if funcList[func]==True:
            eval(f'SomeClass.{func}')(arg1)

只有当FUNC是函数名的作品。 话虽这么说,因为你正在做用户输入使用此方法。 这将是非常容易的调用注入讨厌的代码。 话虽这么说,这样做的工作。



文章来源: Various errors in code that tries to call classmethods [closed]