2174

Pythonプログラムで関数の名前が付いた文字列を指定して、関数を呼び出すための最良の方法は何ですか。たとえば、モジュールfooがあり、内容が。である文字列があるとします"bar"。電話をかける最良の方法は何foo.bar()ですか?

関数の戻り値を取得する必要があるため、を使用するだけではありませんevalevalその関数呼び出しの結果を返す一時関数を定義するためにを使用してそれを行う方法を理解しましたが、これを行うためのより洗練された方法があることを望んでいます。

4

18 に答える 18

2595

fooメソッドを使用したモジュールの想定bar

import foo
method_to_call = getattr(foo, 'bar')
result = method_to_call()

2行目と3行目を次のように短縮できます。

result = getattr(foo, 'bar')()

それがあなたのユースケースにとってより理にかなっているなら。

getattrこの方法で、クラスインスタンスにバインドされたメソッド、モジュールレベルのメソッド、クラスメソッドで使用できます...リストは続きます。

于 2008-08-06T03:57:16.820 に答える
673
locals()["myfunction"]()

また

globals()["myfunction"]()

localsは、現在のローカル シンボル テーブルを含む辞書を返します。globalsは、グローバル シンボル テーブルを含む辞書を返します。

于 2009-05-07T12:45:13.747 に答える
412

パトリックのソリューションはおそらく最もクリーンです。モジュールも動的に取得する必要がある場合は、次のようにインポートできます。

module = __import__('foo')
func = getattr(module, 'bar')
func()
于 2008-08-07T11:35:23.323 に答える
149

単純な貢献です。インスタンス化する必要があるクラスが同じファイルにある場合は、次のようなものを使用できます。

# Get class from globals and create an instance
m = globals()['our_class']()

# Get the function (from the instance) that we need to call
func = getattr(m, 'function_name')

# Call it
func()

例えば:

class A:
    def __init__(self):
        pass

    def sampleFunc(self, arg):
        print('you called sampleFunc({})'.format(arg))

m = globals()['A']()
func = getattr(m, 'sampleFunc')
func('sample arg')

# Sample, all on one line
getattr(globals()['A'](), 'sampleFunc')('sample arg')

そして、クラスでない場合:

def sampleFunc(arg):
    print('you called sampleFunc({})'.format(arg))

globals()['sampleFunc']('sample arg')
于 2012-08-19T09:40:43.627 に答える
139

関数への完全な python パスを含む文字列を指定すると、これが関数の結果を取得する方法です。

import importlib
function_string = 'mypackage.mymodule.myfunc'
mod_name, func_name = function_string.rsplit('.',1)
mod = importlib.import_module(mod_name)
func = getattr(mod, func_name)
result = func()
于 2013-10-16T00:24:22.033 に答える
39

関数(またはクラス)名とアプリ名を文字列として渡す必要がある場合は、次のようにします。

myFnName  = "MyFn"
myAppName = "MyApp"
app = sys.modules[myAppName]
fn  = getattr(app,myFnName)
于 2012-02-14T05:55:36.507 に答える
37

これを試して。これはまだ eval を使用していますが、現在のコンテキストから関数を呼び出すためだけに使用しています。次に、必要に応じて使用する実際の機能があります。

これによる私にとっての主な利点は、関数を呼び出す時点で eval 関連のエラーが発生することです。次に、呼び出し時に関数関連のエラーのみを取得します。

def say_hello(name):
    print 'Hello {}!'.format(name)

# get the function by name
method_name = 'say_hello'
method = eval(method_name)

# call it like a regular function later
args = ['friend']
kwargs = {}
method(*args, **kwargs)
于 2016-12-07T18:29:30.357 に答える
19

提案されたものはどれも私を助けませんでした。私はこれを発見しました。

<object>.__getattribute__(<string name>)(<params>)

私はpython 2.66を使用しています

お役に立てれば

于 2012-12-28T16:56:45.310 に答える
15

この質問として、変数へのメソッド名の割り当てを使用してクラス内でメソッドを動的に呼び出す方法 [重複]は、この質問のように重複としてマークされているため、関連する回答をここに投稿しています。

シナリオは、クラス内のメソッドが同じクラスの別のメソッドを動的に呼び出したいということです。元の例にいくつかの詳細を追加しました。これにより、より広いシナリオと明確さが提供されます。

class MyClass:
    def __init__(self, i):
        self.i = i

    def get(self):
        func = getattr(MyClass, 'function{}'.format(self.i))
        func(self, 12)   # This one will work
        # self.func(12)    # But this does NOT work.


    def function1(self, p1):
        print('function1: {}'.format(p1))
        # do other stuff

    def function2(self, p1):
        print('function2: {}'.format(p1))
        # do other stuff


if __name__ == "__main__":
    class1 = MyClass(1)
    class1.get()
    class2 = MyClass(2)
    class2.get()

出力 (Python 3.7.x)

関数 1: 12

関数 2: 12

于 2019-03-26T18:15:53.643 に答える
2

文字列を関数に変換するという同様の問題に直面しています。しかし、このコードをすぐに実行したくないので、またはを使用できません。eval()ast.literal_eval()

たとえば、 stringがあり、それを string ではなく関数名として"foo.bar"割り当てたいとします。これは、 ON DEMANDxで関数を呼び出すことができることを意味します。x()

ここに私のコードがあります:

str_to_convert = "foo.bar"
exec(f"x = {str_to_convert}")
x()

あなたの質問に関しては、モジュール名fooとその.{}に次のように追加するだけです。

str_to_convert = "bar"
exec(f"x = foo.{str_to_convert}")
x()

警告!!!または危険eval()exec()方法ですので、安全性を確認してください。 警告!!!または危険eval()exec()方法ですので、安全性を確認してください。 警告!!!または危険eval()exec()方法ですので、安全性を確認してください。

于 2021-06-15T08:14:59.950 に答える