75

我正在尝试使用函数式编程来创建一个字典,其中包含一个键和一个要执行的函数:

myDict={}
myItems=("P1","P2","P3",...."Pn")
def myMain(key):
    def ExecP1():
        pass
    def ExecP2():
        pass
    def ExecP3():
        pass
        ...
    def ExecPn():
        pass  

现在,我看到了用于在模块中查找已定义函数的代码,我需要执行以下操作:

    for myitem in myItems:
        myDict[myitem] = ??? #to dynamically find the corresponding function

所以我的问题是,如何列出所有Exec功能,然后使用字典将它们分配给所需的项目?所以最后我会有myDict["P1"]() #this will call ExecP1()

我真正的问题是我有很多这些项目,我制作了一个可以处理它们的库,所以最终用户只需要调用myMain("P1")

我认为使用检查模块,但我不太确定该怎么做。

我避免的原因:

def ExecPn():
    pass
myDict["Pn"]=ExecPn

是我必须保护代码,因为我使用它在我的应用程序中提供脚本功能。

4

11 回答 11

170

简化,简化,简化:

def p1(args):
    whatever

def p2(more args):
    whatever

myDict = {
    "P1": p1,
    "P2": p2,
    ...
    "Pn": pn
}

def myMain(name):
    myDict[name]()

这就是你所需要的。


如果引用无效函数, 您可能会考虑使用dict.getwith 可调用默认值——</p>name

def myMain(name):
    myDict.get(name, lambda: 'Invalid')()

(从 Martijn Pieters 那里得到了这个巧妙的技巧)

于 2012-02-06T22:37:10.067 回答
30

简化,简化,简化+ DRY:

tasks = {}
task = lambda f: tasks.setdefault(f.__name__, f)

@task
def p1():
    whatever

@task
def p2():
    whatever

def my_main(key):
    tasks[key]()
于 2016-09-09T16:20:12.410 回答
28

不骄傲,但是:

def myMain(key):
    def ExecP1():
        pass
    def ExecP2():
        pass
    def ExecP3():
        pass
    def ExecPn():
        pass 
    locals()['Exec' + key]()

但是,我确实建议您将它们放在模块/类中,这真是太可怕了。


如果您愿意为每个函数添加一个装饰器,您可以定义一个装饰器,将每个函数添加到字典中:

def myMain(key):
    tasks = {}
    
    def task(task_fn):
        tasks[task_fn.__name__] = task_fn
    
    @task
    def ExecP1():
        print(1)
    @task
    def ExecP2():
        print(2)
    @task
    def ExecP3():
        print(3)
    @task
    def ExecPn():
        print(4)
    
    tasks['Exec' + key]()

另一种选择是将所有函数放在一个类下(或不同的模块中)并使用getattr

def myMain(key):
    class Tasks:
        def ExecP1():
            print(1)
        def ExecP2():
            print(2)
        def ExecP3():
            print(3)
        def ExecPn():
            print(4)
    
    task = getattr(Tasks, 'Exec' + key)
    task()
于 2012-02-06T22:47:37.143 回答
9
# index dictionary by list of key names

def fn1():
    print "One"

def fn2():
    print "Two"

def fn3():
    print "Three"

fndict = {"A": fn1, "B": fn2, "C": fn3}

keynames = ["A", "B", "C"]

fndict[keynames[1]]()

# keynames[1] = "B", so output of this code is

# Two
于 2017-05-08T18:31:40.940 回答
4

这将从字典中调用方法

这是带有函数调用的python switch 语句

根据您的要求创建几个模块。如果想传递参数然后传递。

创建一个字典,它将根据需要调用这些模块。

    def function_1(arg):
        print("In function_1")

    def function_2(arg):
        print("In function_2")

    def function_3(fileName):
        print("In function_3")
        f_title,f_course1,f_course2 = fileName.split('_')
        return(f_title,f_course1,f_course2)


    def createDictionary():

        dict = {

            1 : function_1,
            2 : function_2,
            3 : function_3,

        }    
        return dict

    dictionary = createDictionary()
    dictionary[3](Argument)#pass any key value to call the method
于 2018-04-27T08:42:33.327 回答
2
#!/usr/bin/python

def thing_a(arg=None):
    print 'thing_a', arg

def thing_b(arg=None):
    print 'thing_b', arg

ghetto_switch_statement = {
    'do_thing_a': thing_a,
    'do_thing_b': thing_b
}

ghetto_switch_statement['do_thing_a']("It's lovely being an A")
ghetto_switch_statement['do_thing_b']("Being a B isn't too shabby either")

print "Available methods are: ", ghetto_switch_statement.keys()
于 2012-02-06T22:37:33.517 回答
2

你可以使用

myDict = {
    "P1": (lambda x: function1()),
    "P2": (lambda x: function2()),
    ...,
    "Pn": (lambda x: functionn())}
myItems = ["P1", "P2", ..., "Pn"]

for item in myItems:
    myDict[item]()
于 2018-04-19T17:28:40.687 回答
2

通常使用类来封装方法,以下是上述答案的扩展,使用默认方法,以防找不到该方法。

class P:

     def p1(self):
         print('Start')

     def p2(self):
         print('Help')

     def ps(self):
         print('Settings')

     def d(self):
         print('Default function')

     myDict = {
         "start": p1,
         "help": p2,
         "settings": ps
     }

     def call_it(self):
         name = 'start'
         f = lambda self, x : self.myDict.get(x, lambda x : self.d())(self)
         f(self, name)


 p = P()
 p.call_it()
于 2020-02-09T01:10:26.207 回答
1
class CallByName():
    
    def method1(self):
        pass

    def method2(self):
        pass

    def method3(self):
        pass

    def get_method(self, method_name):
        method = getattr(self, method_name)
        return method()


callbyname = CallByName()
method1 = callbyname.get_method(method_name)

```
于 2020-12-22T11:57:54.620 回答
0
def p1( ):
    print("in p1")

def p2():
    print("in p2")

myDict={
    "P1": p1,
    "P2": p2

}

name=input("enter P1 or P2")

我的字典名

于 2017-02-20T17:27:39.883 回答
-2

你在浪费时间:

  1. 您将要编写大量无用的代码并引入新的错误。
  2. P1要执行该功能,您的用户无论如何都需要知道名称。
  3. 等等等等等等。

只需将所有函数放入.py文件中:

# my_module.py

def f1():
    pass

def f2():
    pass

def f3():
    pass

并像这样使用它们:

import my_module

my_module.f1()
my_module.f2()
my_module.f3()

或者:

from my_module import f1
from my_module import f2
from my_module import f3

f1()
f2()
f3()

这对于初学者来说应该足够了。

于 2012-02-06T22:49:29.110 回答