在Python中,如何从列表中执行函数对象?

时间:2013-08-13 21:25:06

标签: python

我在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

5 个答案:

答案 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)