我有这样的代码:
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"
我无法弄清楚什么是不对的,并希望得到您的帮助。
直到类已经被定义不能创建到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')
我发现了一些今晚将在这里帮助:我们可以解开魔法staticmethod
和classmethod
通过对象: getattr(func, '__func__')
我是怎么找到这些信息? 使用JetBrains公司PyCharm(我不知道其他的Python IDE)中,我看到的源代码@staticmethod
和@classmethod
。 这两个类定义属性__func__
。
“剩下的就留给读者自己练习。”
所有其他的答案建议加上外界一些代码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
添加自己作为类中的每个方法的参数。
也
if _name__='main'
SomeClass.func3('Argumentus-Primus')
应该是这样的:
if __name__=='__main__':
SomeClass.func3('Argumentus-Primus')
而不应该是类的体内。
您可能需要尝试的静态方法。
@staticmethod
def function():...
静态方法不通过类作为一个隐含的第一个参数。
这里有一个糟糕的方式做到这一点:
def func3(cls,arg1):
global funcList
for func in funcList:
if funcList[func]==True:
eval(f'SomeClass.{func}')(arg1)
只有当FUNC是函数名的作品。 话虽这么说,因为你正在做用户输入不使用此方法。 这将是非常容易的调用注入讨厌的代码。 话虽这么说,这样做的工作。