使用字典选择要执行的函数

问题描述 投票:0回答:12

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

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

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

python function dictionary inspect
12个回答
201
投票

简化,简化,简化:

def p1(args):
    whatever

def p2(more args):
    whatever

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

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

这就是您所需要的。


如果

dict.get
引用无效函数,您可以考虑使用
name
和可调用默认值 —

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

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


32
投票

简化,简化,简化 + 干燥:

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

@task
def p1():
    whatever

@task
def p2():
    whatever

def my_main(key):
    tasks[key]()

29
投票

并不为此感到自豪,但是:

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()

10
投票
# 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

5
投票

你可以直接使用

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

for item in myItems:
    myDict[item]()

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

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()

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()

2
投票
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)

```

0
投票
def p1( ):
    print("in p1")

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

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

}

name=input("enter P1 or P2")

我的字典名称


0
投票
# Define your functions here (replace with actual function definitions)

# Function that simulates calling FunctionA with parameters
def FunctionA(param1, param2):
    print(f"Calling FunctionA with params: {param1}, {param2}")

# Function that simulates calling FunctionB with parameters
def FunctionB(img_ch, output_ch, lamda, start_n):
    print(f"Calling FunctionB with params: {img_ch}, {output_ch}, {lamda}, {start_n}")

# Function that simulates calling FunctionC
def FunctionC():
    print("Calling FunctionC")

# Function that simulates calling FunctionD with parameters
def FunctionD(param1, param2):
    print(f"Calling FunctionD with params: {param1}, {param2}")

# Your dictionary
a = {
    'FunctionX': 'FunctionA(9, 5)',
    'FunctionY': 'FunctionB(img_ch=3,output_ch=2,lamda=0.1,start_n=16)',
    'FunctionZ': 'FunctionA(9,3)',
    'FunctionW': 'FunctionC()',
    'FunctionP': 'FunctionD(3,2)'
}

# Loop through the dictionary
for key, value in a.items():
    try:
        # Evaluate the value as a function call
        eval(value)
    except Exception as e:
        print(f"Error calling {key}: {e}")

输出:

Calling FunctionA with params: 9, 5
Calling FunctionB with params: 3, 2, 0.1, 16
Calling FunctionA with params: 9, 3
Calling FunctionC
Calling FunctionD with params: 3, 2

-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()

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

© www.soinside.com 2019 - 2024. All rights reserved.