我在Python方面相当新,似乎无法让它发挥作用。我有一个列表,其中包含一个嵌入的对象列表,这些对象是函数的名称,我需要执行对象列表。我有调用函数列表的函数。我想改变它,所以我可以直接调用函数列表而不需要调用另一个函数。
validActions=[
['Refresh','Environment Refresh',Refresh],
['Retire','Environment Retire Storage',
[ doStatusDecommission,
doPauseJobBeforeStart,
doRetireStorage,
doStatusDisconnected]],
['Provision','Environment Provision Storage',Provision]
]
def updateEnv(ctx):
for actionVal,actionDesc,actionFunction in validActions:
if ctx["newAction"] == actionVal:
actionFunction()
如果我将“刷新”或“提供”称为功能,则此方法有效。但是,当我将列表调用为“Retire”并且错误消息为
时,这不起作用TypeError: 'list' object is not callable
答案 0 :(得分:3)
您仍然可以调用列表中的每个功能。如果您创建所有条目列表,则处理这两种情况变得更加容易:
validActions=[
['Refresh','Environment Refresh', [Refresh]],
['Retire','Environment Retire Storage', [
doStatusDecommission,
doPauseJobBeforeStart,
doRetireStorage,
doStatusDisconnected
]],
['Provision', 'Environment Provision Storage', [Provision]]
]
def updateEnv(ctx):
for actionVal, actionDesc, actionFunctions in validActions:
if ctx["newAction"] == actionVal:
for action_function in actionFunctions:
action_function()
如果您所做的只是找到与ctx['newAction']
匹配的一个操作,那么您最好使用字典并查找actionDesc
和{{1直接来自*的项目:
actionFunctions
答案 1 :(得分:1)
制作所有列表,然后依次遍历执行每个列表的列表。
for actionVal,actionDesc,actionFunctions in validActions:
if ctx["newAction"] == actionVal:
for actionFunction in actionFunctions:
actionFunction()
答案 2 :(得分:1)
一个选项是让每个列表以函数列表结束,即使列表只有一个元素
validActions=[
['Refresh','Environment Refresh', [Refresh]], #note brackets around Refresh
['Retire','Environment Retire Storage',
[ doStatusDecommission,
doPauseJobBeforeStart,
doRetireStorage,
doStatusDisconnected]],
['Provision','Environment Provision Storage',[Provision]]
]
def updateEnv(ctx):
for actionVal,actionDesc,actionFunctions in validActions:
if ctx["newAction"] == actionVal:
for func in actionFunctions:
func()
或者创建一个调用所有这四个函数的新函数
def retireFunctions():
doStatusDecommission()
doPauseJobBeforeStart()
doRetireStorage()
doStatusDisconnected()
validActions=[
['Refresh','Environment Refresh',Refresh],
['Retire','Environment Retire Storage', retireFunctions],
['Provision','Environment Provision Storage',Provision]
]
或最终选项是型式测试(不推荐)
def updateEnv(ctx):
for actionVal,actionDesc,actionFunction in validActions:
if ctx["newAction"] == actionVal:
if callable(actionFunction):
actionFunction()
else:
for func in actionFunction:
func()
答案 3 :(得分:0)
我不想用你定义的列表填写我的答案,以使它看起来更长。我将使用您定义的相同列表。
def updateEnv(ctx):
for actionVal,actionDesc,actionFunctions in validActions:
if ctx["newAction"] == actionVal:
try:
[func() for func in actionFunctions]
except TypeError:
# not iterable
actionFunctions()
except Exception as e:
# iterable, unexpected errors
print e
pass
如果您可以修改数据结构,我建议如下:
validActions={
('Refresh','Environment Refresh') : {Refresh},
('Retire','Environment Retire Storage'):
{ doStatusDecommission,
doPauseJobBeforeStart,
doRetireStorage,
doStatusDisconnected } ,
('Provision','Environment Provision Storage'):{Provision}
}
您的函数通常是方法描述符,它们是不可变的。使用set作为函数的容器可以大大减少迭代和计数的时间成本。
通过使用字典作为具有元组键的顶级容器,您可以准确地将输入映射到输出。那是什么意思?这意味着:
def updateEnv(ctx):
[[func() for func in value] if ctx["newAction"] == key[0]
else None
for key, value in validActions.items()]
更有效率,如果你知道actionDecs对actionVal是唯一的,那么使用两个单独的映射:
validActions = {
'Refresh' : {Refresh},
'Retire':
{ doStatusDecommission,
doPauseJobBeforeStart,
doRetireStorage,
doStatusDisconnected } ,
'Provision' : {Provision}
}
actionsDescs = {
'Refresh': 'Environment Refresh'
'Retire': 'Environment Retire Storage'
'Provision' : 'Environment Provision Storage'
}
如果您需要缩写说明,请致电:
actionsDescs['Refresh']
你的函数迭代变为:
def updateEnv(ctx):
[func() for func in validAction[ctx["newAction"]]]
如果您对此有特殊需求或疑问,请随时发表评论。
答案 4 :(得分:-1)
按名称获取功能
如果本模块中定义的功能:
globals().get(actionFunctionName)(args)
如果在其他模块或班级中:
getattr(class_or_module,actionFunctionName)(args)