我有这段代码:
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"
我无法弄清楚这有什么问题,非常感谢你的帮助。
答案 0 :(得分: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')
答案 1 :(得分:10)
今晚我发现了一些在这里有用的内容:我们可以通过以下方式展开魔术staticmethod
和classmethod
对象<{1}}
我是如何找到这些信息的?使用JetBrains的PyCharm(我不知道其他Python IDE),我查看了getattr(func, '__func__')
和@staticmethod
的源代码。这两个类都定义了属性@classmethod
。
“其余部分留给读者练习。”
答案 2 :(得分:1)
所有其他答案建议在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
方法时都不会构造新的字典。这很容易,我并没有为了保持示例的简洁明了而做。
在python 3.6上测试
答案 3 :(得分:0)
添加 self 作为类中每个方法的参数。
另外
if _name__='main'
SomeClass.func3('Argumentus-Primus')
应如下所示:
if __name__=='__main__':
SomeClass.func3('Argumentus-Primus')
并且不应该在班级的主体内。
答案 4 :(得分:0)
您可能需要尝试静态方法。
@staticmethod
def function():...
静态方法不会将类作为隐式的第一个参数传递。
答案 5 :(得分:0)
这是一个糟糕的方法:
def func3(cls,arg1):
global funcList
for func in funcList:
if funcList[func]==True:
eval(f'SomeClass.{func}')(arg1)
仅在函数名称为func时有效。话虽如此,请勿使用此方法,因为您正在接受用户输入。在调用中注入讨厌的代码将非常容易。话虽如此,这确实有效。