Pythonプログラムで関数の名前が付いた文字列を指定して、関数を呼び出すための最良の方法は何ですか。たとえば、モジュールfoo
があり、内容が。である文字列があるとします"bar"
。電話をかける最良の方法は何foo.bar()
ですか?
関数の戻り値を取得する必要があるため、を使用するだけではありませんeval
。eval
その関数呼び出しの結果を返す一時関数を定義するためにを使用してそれを行う方法を理解しましたが、これを行うためのより洗練された方法があることを望んでいます。
foo
メソッドを使用したモジュールの想定bar
:
import foo
method_to_call = getattr(foo, 'bar')
result = method_to_call()
2行目と3行目を次のように短縮できます。
result = getattr(foo, 'bar')()
それがあなたのユースケースにとってより理にかなっているなら。
getattr
この方法で、クラスインスタンスにバインドされたメソッド、モジュールレベルのメソッド、クラスメソッドで使用できます...リストは続きます。
パトリックのソリューションはおそらく最もクリーンです。モジュールも動的に取得する必要がある場合は、次のようにインポートできます。
module = __import__('foo')
func = getattr(module, 'bar')
func()
単純な貢献です。インスタンス化する必要があるクラスが同じファイルにある場合は、次のようなものを使用できます。
# 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')
関数への完全な 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()
関数(またはクラス)名とアプリ名を文字列として渡す必要がある場合は、次のようにします。
myFnName = "MyFn"
myAppName = "MyApp"
app = sys.modules[myAppName]
fn = getattr(app,myFnName)
これを試して。これはまだ 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)
提案されたものはどれも私を助けませんでした。私はこれを発見しました。
<object>.__getattribute__(<string name>)(<params>)
私はpython 2.66を使用しています
お役に立てれば
この質問として、変数へのメソッド名の割り当てを使用してクラス内でメソッドを動的に呼び出す方法 [重複]は、この質問のように重複としてマークされているため、関連する回答をここに投稿しています。
シナリオは、クラス内のメソッドが同じクラスの別のメソッドを動的に呼び出したいということです。元の例にいくつかの詳細を追加しました。これにより、より広いシナリオと明確さが提供されます。
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
文字列を関数に変換するという同様の問題に直面しています。しかし、このコードをすぐに実行したくないので、またはを使用できません。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()
方法ですので、安全性を確認してください。