Ceea ce este cel mai bun mod de a merge despre apelarea unei funcții dat un șir de caractere cu funcția's nume într-un program in Python. De exemplu, să's spun că am un modul de "foo", și am un șir de caractere al căror conținut este"bar". Ceea ce este cel mai bun mod de a suna
foo.bar()`?
Am nevoie pentru a obține valoarea returnată de funcție, care este de ce eu nu't de a folosi doar "eval". Mi-am dat seama cum să o facă prin utilizarea "eval" pentru a defini o temp funcție care returnează rezultatul acestui apel de funcție, dar nu'm sperând că nu există un mod mai elegant de a face acest lucru.
Presupunând că modulul " foo "cu metodă "bar":
import foo
method_to_call = getattr(foo, 'bar')
result = method_to_call()
Ai putea scurta liniile 2 și 3:
result = getattr(foo, 'bar')()
în cazul în care face mai mult sens pentru cazul dumneavoastră de utilizare.
Puteți utiliza getattr
în acest mod la clasă exemplu legat metode, module la nivel de metode, metode de clasă... lista poate continua.
Patrick's soluție este, probabil, cel mai curat. Dacă aveți nevoie pentru a dinamic ridica modulul fel de bine, puteți să-l importați, cum ar fi:
module = __import__('foo')
func = getattr(module, 'bar')
func()
Doar o simplă contribuție. În cazul în care clasa de care avem nevoie spre exemplu, este în același fișier, putem folosi ceva de genul asta:
# 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()
De exemplu:
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')
Și, dacă nu o clasă:
def sampleFunc(arg):
print('you called sampleFunc({})'.format(arg))
globals()['sampleFunc']('sample arg')
Dat un șir de caractere, cu un completați calea python pentru o funcție, acest lucru este cum m-am dus despre obtinerea rezultatul a declarat funcție:
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()
Cel mai bun răspuns potrivit de programare Python FAQ ar fi:
functions = {'myfoo': foo.bar}
mystring = 'myfoo'
if mystring in functions:
functions[mystring]()
principalul avantaj al acestei tehnici este faptul că siruri de caractere nu au nevoie pentru a se potrivi numele de funcții. Acest lucru este, de asemenea, principala tehnică utilizată pentru a emula un caz construct
Raspunsul (sper) nimeni nu a vrut
Eval astfel de comportament
getattr(locals().get("foo") or globals().get("foo"), "bar")()
De ce nu-l adăugați auto-importul
getattr(
locals().get("foo") or
globals().get("foo") or
__import__("foo"),
"bar")()
În cazul în care avem dicționare suplimentare vrem să verificăm
getattr(next((x for x in (f("foo") for f in
[locals().get, globals().get,
self.__dict__.get, __import__])
if x)),
"bar")()
Trebuie să mergem mai adânc
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")()
Pentru ce-l's valoare, dacă aveți nevoie pentru a trece funcția (sau clasa) numele și numele app ca un șir de caractere, atunci ai putea face acest lucru:
myFnName = "MyFn"
myAppName = "MyApp"
app = sys.modules[myAppName]
fn = getattr(app,myFnName)
Încercați acest lucru. În timp ce aceasta încă mai folosește eval, se folosește numai la convoca în funcție de contextul actual. Apoi, aveți o funcție reală de a folosi cum doriti.
Principalul beneficiu pentru mine de la acest lucru este că veți obține orice eval-erori legate la punctul de citarea funcției. Atunci veți obține numai funcția legate de erori atunci când te sun.
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)
Ca această întrebare Cum pentru a dinamic a apela metode dintr-o clasă folosind metoda-numele misiune la o variabilă [duplicat] a marcat ca un duplicat ca asta, eu sunt de a posta un legate de răspunsul aici:
Scenariul este, o metodă într-o clasă doriți pentru a apela o altă metodă pe aceeași clasă dinamic, am adăugat unele detalii originale exemplu care oferă un scenariu mai amplu și claritate:
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()
de Ieșire (Python 3.7.x)
function1: 12
function2: 12
Acesta este un răspuns simplu, acest lucru vă va permite pentru a goli ecranul, de exemplu. Există două exemple de mai jos, cu eval și executiv, care se va imprima 0 în partea de sus după curățare (daca're folosind Windows, schimbare "clear" pentru a cls
, Linux și Mac, utilizatorii lăsați așa cum este, de exemplu) sau doar executa, respectiv.
eval("os.system(\"clear\")")
exec("os.system(\"clear\")")