Apa adalah cara terbaik untuk pergi tentang memanggil fungsi yang diberikan sebuah string dengan fungsi's nama di Python program. Misalnya, let's mengatakan bahwa saya memiliki modul foo
, dan aku punya string yang isinya adalah "bar"
. Apa cara terbaik untuk panggilan foo.bar()
?
Saya perlu untuk mendapatkan nilai kembali dari fungsi, yang adalah mengapa saya don't hanya menggunakan eval
. Aku tahu bagaimana melakukan ini dengan menggunakan eval
untuk menentukan temp fungsi yang mengembalikan hasil dari fungsi yang memanggil, tapi aku'm berharap bahwa ada cara yang lebih elegan untuk melakukan hal ini.
Dengan asumsi modul foo
dengan metode bar
:
import foo
method_to_call = getattr(foo, 'bar')
result = method_to_call()
Anda bisa mempersingkat jalur 2 dan 3 untuk:
result = getattr(foo, 'bar')()
jika itu lebih masuk akal untuk kasus anda.
Anda dapat menggunakan getattr
dalam mode ini pada kelas contoh terikat metode, modul metode tingkat, kelas metode... daftar goes on.
Patrick's solusi yang mungkin adalah yang terbersih. Jika anda perlu untuk secara dinamis mengambil modul juga, anda dapat mengimpor seperti:
module = __import__('foo')
func = getattr(module, 'bar')
func()
Hanya sederhana kontribusi. Jika kelas yang perlu kita contoh adalah di file yang sama, kita dapat menggunakan sesuatu seperti ini:
# 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()
Misalnya:
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')
Dan, jika tidak kelas:
def sampleFunc(arg):
print('you called sampleFunc({})'.format(arg))
globals()['sampleFunc']('sample arg')
Diberikan sebuah string, dengan lengkap python path untuk fungsi, ini adalah bagaimana aku pergi tentang mendapatkan hasil dari fungsi tersebut:
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()
Jawaban terbaik menurut pemrograman Python FAQ akan sama:
functions = {'myfoo': foo.bar}
mystring = 'myfoo'
if mystring in functions:
functions[mystring]()
keuntungan utama dari teknik ini adalah bahwa string tidak perlu untuk mencocokkan nama-nama fungsi. Ini juga merupakan teknik utama yang digunakan untuk meniru hal membangun
Jawaban yang (saya harap) tidak ada yang pernah ingin
Eval seperti perilaku
getattr(locals().get("foo") or globals().get("foo"), "bar")()
Mengapa tidak menambahkan auto-impor
getattr(
locals().get("foo") or
globals().get("foo") or
__import__("foo"),
"bar")()
Dalam hal ini kita harus ekstra kamus kita ingin memeriksa
getattr(next((x for x in (f("foo") for f in
[locals().get, globals().get,
self.__dict__.get, __import__])
if x)),
"bar")()
Kita harus pergi lebih dalam
getattr(next((x for x in (f("foo") for f in
([locals().get, globals().get, self.__dict__.get] +
[d.get for d in (list(dd.values()) for dd in
[locals(),globals(),self.__dict__]
if isinstance(dd,dict))
if isinstance(d,dict)] +
[__import__]))
if x)),
"bar")()
Untuk apa itu's worth, jika anda perlu untuk melewati fungsi (atau kelas) nama dan nama aplikasi sebagai string, maka anda bisa melakukan hal ini:
myFnName = "MyFn"
myAppName = "MyApp"
app = sys.modules[myAppName]
fn = getattr(app,myFnName)
Mencoba ini. Sementara ini masih menggunakan eval, itu hanya menggunakannya untuk memanggil fungsi dari konteks saat ini. Kemudian, anda memiliki fungsi nyata untuk menggunakan seperti yang anda inginkan.
Manfaat utama dari ini adalah bahwa anda akan mendapatkan eval terkait kesalahan pada saat pemanggilan fungsi. Maka anda akan mendapatkan hanya fungsi yang berhubungan dengan kesalahan ketika anda menelepon.
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)
Sebagai pertanyaan ini Bagaimana untuk secara dinamis memanggil metode dalam kelas yang menggunakan metode-nama assignment untuk variabel [duplikat] ditandai sebagai duplikat seperti yang satu ini, saya posting berkaitan dengan jawaban berikut ini:
Dalam skenario ini, sebuah metode di kelas ingin memanggil metode lain pada kelas yang sama secara dinamis, saya telah menambahkan beberapa rincian untuk contoh asli yang menawarkan beberapa skenario yang lebih luas dan kejelasan:
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()
Output (Python 3.7.x)
function1: 12
function2: 12
Ini adalah jawaban sederhana, ini akan memungkinkan anda untuk membersihkan layar misalnya. Ada dua contoh di bawah ini, dengan eval dan exec, yang akan mencetak 0 di bagian atas setelah pembersihan (jika anda're menggunakan Windows, mengubah jelas
untuk cls
, pengguna Linux dan Mac meninggalkan seperti misalnya) atau hanya menjalankan itu, masing-masing.
eval("os.system(\"clear\")")
exec("os.system(\"clear\")")