【问题标题】:Methods stored as strings into methods that run [duplicate]以字符串形式存储到运行的方法中的方法[重复]
【发布时间】:2019-02-21 17:03:11
【问题描述】:

我有一本这样的字典:

dictionary = { "a":function_1(), "b":function_2(), "c":function_3()}

但由于我不想在声明字典时运行所有函数,所以我将它们存储为字符串:

dictionary = { "a":"function_1()", "b":"function_2()", "c":"function_3()"}

我想做的是根据与之关联的键只调用一个函数:

for key,value in dictionary.items():
     if key == something:
          wanted_variable = value

如果我现在打印 Wanted_variable,它将返回“function_1()”,我希望它是 function_1() 返回的内容...

谁能帮帮我?

【问题讨论】:

    标签: python python-3.x dictionary


    【解决方案1】:

    由于函数是第一类对象,您可以在不调用它们的情况下传递对它们的引用,并在以后调用它们:

    dictionary = {
        "a":function_1,  # No parens here anymore
        "b":function_2,  # ''
        "c":function_3,  # ''
    }
    
    for key,value in dictionary.items():
         if key == something:
              # "Calling" parens here, not in the dictionary values
              wanted_variable = value()   
    

    或者,

    dictionary = {
        "a":function_1,  # No parens here anymore
        "b":function_2,  # ''
        "c":function_3,  # ''
    }
    
    func = dictionary.get(key)
    if func:
        wanted_variable = func()
    

    最终会做同样的事情,但不必遍历字典项。

    对于更复杂的场景,当你想要捕获一个未调用的函数但该函数的参数时,还有functools.partial

    from functools import partial
    
    dictionary = {
        "a":partial(function_1, 123), 
        "b":partial(function_2, 456), 
        "c":partial(function_3, 789),
    }
    
    for key,value in dictionary.items():
         if key == something:
              # "Calling" parens here, not in the dictionary values
              # This will actually call, for example, function_1(123).
              wanted_variable = value()   
    

    例如:

    from functools import partial
    
    def foo(x):
        print("x is", x)
    
    wrapped_foo = partial(foo, 123)
    
    # Pass wrapped_foo around however you want...
    d = {'func': wrapped_foo}
    
    # Call it later
    d['func']()   # Prints "foo is 123"
    

    【讨论】:

    • 循环不是必需的;只有一个键可以匹配something,所以直接索引字典即可。
    • @chepner 我专注于 OP 的问题,但很好 - 我使用 dict.get 在第一个块下添加了一个替代方案。
    【解决方案2】:

    无需调用即可存储函数:

    dictionary = { "a":function_1, "b":function_2, "c":function_3}  # no ()
    

    然后

    for key, value in dictionary.items():
        if key == something:
            wanted_variable = value()
    

    顺便说一句,还有更有效的获取wanted_variable的方法:

    if something in dictionary:
        wanted_variable = dictionary[something]()
    

    【讨论】:

    • 你也可以使用“wanted_variable = dictionary[something]()”代替循环比较
    • 如果dictionary 不包含something,我不能
    • 然后检查something是否在字典中;无需先遍历所有键。 if something in dictionary: wanted_variable = dictionary[something]().
    • 我们都在复制 OP 的代码示例,但你是对的,我更新了我的答案
    • 第一次你检查了字典n 次,最近你检查了两次,但是你可以用类似func = dictionary.get(something); if func: func()的东西检查一次
    【解决方案3】:

    你需要用函数名来定义字典:

    dictionary = {"a":function_1, "b":function_2, "c":function_3}
    

    如果你在函数名后面加上括号,你会立即调用它。

    调用需要的函数匹配为:

    for key, value in dictionary.items():
         if key == 'a':
              wanted_variable = value()
    

    【讨论】:

      【解决方案4】:

      你可以只存储函数而不调用它们:

      dictionary = { "a":function_1, "b":function_2, "c":function_3}
      

      然后:

      for key,value in dictionary.items():
           if key == something:
                wanted_variable = value()
      

      【讨论】:

        【解决方案5】:

        你可以存储不带 () 的函数,这样它们就不会执行,那么你可以这样做:

        def func1():
           x = "func1"
           print(x)
           return x
        def func2():
           x = "func2"
           print(x)
           return x
        
        
        d = {"a":func1, "b":func2}
        
        wanted_variable = d["a"]()
        

        【讨论】:

        • 循环也不是必需的:wanted_variable = d["a"]().
        • 没错,我编辑了。谢谢@chepner!。
        【解决方案6】:

        eval 是对您的这个问题的更简单和实际的答案。

        dictionary = { "a":"function_1()", "b":"function_2()", "c":"function_3()"}
        
        for key, value in dictionary.items():
            if key == something:
                wanted_variable = eval(value)
        

        【讨论】:

        • 如果您在字典中存储对函数的引用,则 all 中不需要eval
        • 我已将函数作为字符串存储在字典中。不是参考。这行不通?
        • 是的。不要那样做。
        • @chepner 这实际上是问题提出的确切情况。尽管我同意这不是最好的方法(请参阅其他答案)并且您的评论是有效的,但我确实认为这是一个有价值且正确的答案
        • 是的。我也得到了预期的输出。
        猜你喜欢
        • 2019-11-01
        • 2012-04-25
        • 2012-08-02
        • 2020-10-08
        • 2012-07-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-24
        相关资源
        最近更新 更多