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

inspect モジュールを使用していると思いますが、その方法がよくわかりません。

避けるべき私の理由:

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.get無効な関数を参照している場合は、呼び出し可能なデフォルトで を使用することを検討してくださいname—</p>

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

(Martijn Pieters からこの巧妙なトリックを取り上げました)

于 2012-02-06T22:37:10.067 に答える
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 に答える
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

あなたはあなたの時間を無駄にしています:

  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 に答える