【问题标题】:How to call function from list if exists如果存在,如何从列表中调用函数
【发布时间】:2019-10-23 20:52:24
【问题描述】:

我有一个函数列表并且需要调用一个函数,如果该函数存在于该列表中。另外,我需要用字符串调用函数。

我尝试过这样做:

if "func1" in funcs:
    funcs.__getitem__("func1")

但我做错了

funcs = [func1, func2, func3]

def func1: return 1
def func2: return 2
def func3: return 3

if "func1" in funcs:
    # call func1 since it exists

我希望输出为1,但我不知道如何调用该函数。 另外,这不是重复的,因为我不会从类中调用该函数。

【问题讨论】:

标签: python


【解决方案1】:

发现我将只使用字典。容易得多。

funcs = {"func1": func1, etc..}

def func1(): return 1
def etc..

if "func1" in funcs:
    funcs["funcs1"]()

【讨论】:

  • locals()globals() 已经提供了字典,尽管还有一些额外的内容。
  • @TrebledJ 确实如此,这就是为什么在此处的上下文中推荐或提及它们是不好的形式。与使用您自己的字典专门将字符串映射到您自己的函数以向最终用户公开相比,这是一个更糟糕的选择。 (让我们看看如果授予对全局变量的访问权限,它们会造成什么混乱。?)
  • 我在新解决方案中使用了globals()
  • 如果您认为这是一个更好的解决方案,您可能希望接受它(绿色复选标记)而不是其他答案。
【解决方案2】:

您还可以使用类结构和检查模块,这可能会提供更多的灵活性:

import inspect
class funcs:
    def func1(): return 1
    def func2(): return 2
    def func3(): return 3

listfuncs = inspect.getmembers(funcs, lambda a:inspect.isfunction(a))

print(listfuncs)

listfuncs 将是具有函数名称和对象引用的元组列表。

【讨论】:

    【解决方案3】:

    只是在@Gwang-Jin Kim 已经提供的答案上即兴发挥。

    如果你这样做会发生什么?

    def func1():
        return 1
    
    def func2():
        return 2
    
    
    tuple_list = [("func1",func1), ("func2", func2)]
    
    
    if any([items[0] == "func1" for items in tuple_list]):
        print("Do Something")
    

    或者这个

    for key, val in tuple_list:
        if key == "func1":
            print(val())
    

    另外,好像是call list of function using list comprehension的重复问题

    【讨论】:

      【解决方案4】:

      Gwang-Jin Kim 在 Python 被解释这一点上是对的。因此,您的函数需要在调用之前定义。现在,您需要在用户键入该函数的名称时调用该函数。可以运行用户使用 eval() 函数键入的文本;但是,不建议这样做,因为无法确定用户将输入什么内容,这可能会导致不必要的错误。

      我建议您使用命令系统,根据预定义的名称调用函数,如下所示:

      def func1():
          print(1)
      
      
      def func2():
          print(2)
      
      
      while True:
          try:
              msg = input('Which function would you like to call?: ')
      
              if not msg:
                  break
      
              if msg.startswith('func1'):
                  func1()
      
              if msg.startswith('func2'):
                  func2()
          except Exception as e:
              print(e)
              break
      

      【讨论】:

        【解决方案5】:
        def func1(): return 1
        def func2(): return 2
        def func3(): return 3
        
        funcs = [func1, func2, func3]
        funcs_dict = {f.__name__: f for f in funcs}
        
        funcname = "func1"
        
        funcs_dict[funcname]()
        

        这会检查 - 如果函数名在 funcs 中的函数名下,则执行它!

        (可以在 Python 中使用字典来避免 if 检查)。

        如果没有像funcs 这样的列表,则必须使用globals()

        if callable(globals()[funcname]):
            print(globals()[funcname]())
        
        if callable(eval(funcname)):
            print(eval(funcname)())
        

        或:

        try:
            print(eval(funcname)())
        except:
            print("No such functionname: {}".format(funcname))
        

        或:

        try:
            globals()[funcname]()
        except:
            print("No such functionname: {}".format(funcname))
        

        【讨论】:

          猜你喜欢
          • 2017-09-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-11-26
          • 1970-01-01
          • 2016-03-26
          相关资源
          最近更新 更多