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

Joh*_*yDH 40 python dictionary function inspect

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

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

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

    for myitem in myItems:
        myDict[myitem] = ??? #to dynamically find the corresponding function
Run Code Online (Sandbox Code Playgroud)

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

我真正的问题是我有大量的这些项目,我创建了一个库来处理它们,所以最终用户只需要调用 myMain("P1")

我认为使用检查模块,但我不确定如何做到这一点.

我有理由避免:

def ExecPn():
    pass
myDict["Pn"]=ExecPn
Run Code Online (Sandbox Code Playgroud)

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

S.L*_*ott 90

简化,简化和简化:

def p1(args):
    whatever

def p2(more args):
    whatever

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

def myMain(name):
    myDict[name]()
Run Code Online (Sandbox Code Playgroud)

这就是你所需要的.


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

def myMain(name):
    myDict.get(name, lambda: 'Invalid')()
Run Code Online (Sandbox Code Playgroud)

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

  • 用户可以随时在运行时更改他们想要的任何内容.这是Python.他们有源头. (18认同)
  • @JohnnyDH这是一个疯狂的争论.如果您确实需要使代码更"安全",那么您必须使用编译语言 - python不是正确的工具,您有责任向客户解释.在你的代码中添加一行废话以尝试解决python固有的开放性并不是一种安全措施 - 它无法正常完成,并且尝试这样做只会使你的代码变得更加丑陋和脆弱 (10认同)
  • @JohnnyDH:我只提供软件 30 年,所以我之前见过一些无用的复杂性的例子。这是另一个。复杂性和安全性之间存在差异。“如果他们想看...”这行是一个非常非常糟糕的例子,因为 Python 没有像 C 那样的“++”运算符。和。“脚本功能”的解释必须融入到您的问题中,这样您的问题才有意义。在评论中重复要求是**不好**。 (2认同)

Oha*_*had 21

不为此感到自豪,但是:

def myMain(key):
    def ExecP1():
        pass
    def ExecP2():
        pass
    def ExecP3():
        pass
    def ExecPn():
        pass 
    locals()['Exec' + key]()
Run Code Online (Sandbox Code Playgroud)

但是我建议你把它们放在模块/类中,这真的太可怕了.


Joe*_*Joe 20

简化,简化,简化 + DRY:

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

@task
def p1():
    whatever

@task
def p2():
    whatever

def my_main(key):
    tasks[key]()
Run Code Online (Sandbox Code Playgroud)

  • 这不是干,这是混淆的. (6认同)
  • 至少可以这样说,我认为将lambdas和自定义装饰器之类的高级语言功能混淆是令人误解的。 (2认同)
  • 当然。这里的lambda只是为了简洁。无论您坚持使用还是改写为`def task(f):\ n task [f .__ name__] = f`,其原理都保持不变。变干消除了您使字典关键字与函数名称保持同步的责任。它还可以更容易发现错误,例如缺少`@ task`(与缺少字典项相比)。 (2认同)

小智 6

# 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
Run Code Online (Sandbox Code Playgroud)


Jon*_*wer 5

你可以只使用

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

for item in myItems:
    myDict[item]()
Run Code Online (Sandbox Code Playgroud)