Pertanyaan Memanggil fungsi modul dengan menggunakan namanya (string)


Apa cara terbaik untuk memanggil fungsi yang diberikan string dengan nama fungsi dalam program Python. Sebagai contoh, katakanlah saya memiliki modul foo, dan saya memiliki string yang isinya "bar". Apa cara terbaik untuk menelepon? foo.bar()?

Saya harus mendapatkan nilai kembalian dari fungsi tersebut, itulah mengapa saya tidak hanya menggunakannya eval. Saya tahu cara melakukannya dengan menggunakan eval untuk mendefinisikan fungsi temp yang mengembalikan hasil panggilan fungsi itu, tapi saya berharap ada cara yang lebih elegan untuk melakukan ini.


1185
2017-08-06 03:36


asal


Jawaban:


Asumsikan modul foo dengan metode bar:

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

Sejauh yang berjalan, garis 2 dan 3 dapat dikompresi ke:

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

jika itu lebih masuk akal untuk kasus penggunaan Anda. Kamu dapat memakai getattr dalam mode ini pada metode terikat kelas seperti, metode level-modul, metode kelas ... daftarnya terus berlanjut.


1439
2017-08-06 03:57



locals()["myfunction"]()

atau

globals()["myfunction"]()

penduduk setempat mengembalikan kamus dengan tabel simbol lokal saat ini. global mengembalikan kamus dengan tabel simbol global.


401
2018-05-07 12:45



Solusi Patrick mungkin yang paling bersih. Jika Anda perlu mengambil modul secara dinamis juga, Anda dapat mengimpornya seperti:

module = __import__('foo')
func = getattr(module, 'bar')
func()

240
2017-08-07 11:35



Hanya sumbangan sederhana. Jika kelas yang kita perlu contoh ada 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()

Sebagai contoh:

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 bukan kelas:

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

globals()['sampleFunc']('sample arg')

81
2017-08-19 09:40



Diberikan string, dengan path python lengkap ke fungsi, ini adalah bagaimana saya 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()

65
2017-10-16 00:24



Jawabannya (saya harap) tidak ada yang diinginkan

Perilaku seperti Eval

getattr(locals().get("foo") or globals().get("foo"), "bar")()

Mengapa tidak menambahkan impor otomatis

getattr(
    locals().get("foo") or 
    globals().get("foo") or
    __import__("foo"), 
"bar")()

Dalam hal kami memiliki kamus tambahan yang ingin kami periksa

getattr(next((x for x in (f("foo") for f in 
                          [locals().get, globals().get, 
                           self.__dict__.get, __import__]) 
              if x)),
"bar")()

Kita harus masuk 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")()

31
2018-04-09 10:17



Jawaban terbaik menurut FAQ pemrograman Python akan menjadi:

functions = {'myfoo': foo.bar}

mystring = 'myfoo'
if mystring in functions:
    functions[mystring]()

Keuntungan utama dari teknik ini adalah bahwa string tidak perlu sesuai dengan nama fungsi. Ini juga teknik utama yang digunakan untuk meniru sebuah konstruksi kasus


28
2017-10-24 13:20



Untuk apa nilainya, jika Anda perlu memberikan nama fungsi (atau kelas) dan nama aplikasi sebagai string, maka Anda dapat melakukan ini:

myFnName  = "MyFn"
myAppName = "MyApp"
app = sys.modules[myAppName]
fn  = getattr(app,myFnName)

18
2018-02-14 05:55



Coba ini. Meskipun ini masih menggunakan eval, ia hanya menggunakannya memanggil fungsi dari konteks saat ini. Kemudian, Anda memiliki fungsi nyata untuk digunakan sesuai keinginan.

Manfaat utama bagi saya dari ini adalah bahwa Anda akan mendapatkan kesalahan terkait eval pada titik memanggil fungsi. Maka Anda akan dapatkan hanya kesalahan terkait fungsi saat 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)

15
2017-12-07 18:29



tidak ada yang disarankan membantu saya. Saya memang menemukan ini.

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

Saya menggunakan python 2.66

Semoga ini membantu


13
2017-12-28 16:56