Witam,
w pewnym momencie w mojej aplikacji otrzymuję string który odpowiada nazwie funkcji istniejącej w programie.
Jak uruchomić te funkcję? (wartość zmiennej jest nazwą funkcji).
Pozdrawiam,
Jak uruchomić te funkcję? (wartość zmiennej jest nazwą funkcji).
Drogi autorze, tak dla ścisłości - masz swój program, w nim zdefiniowałeś funkcję wedle schematu:
def nazwa_funkcji(ew. parametry):
jakieś operacje
return coś_tam
W pewnym momencie jakaś zmienna w Twym programie przyjmuje wartość "nazwa_funkcji". Czy w tym leży problem?
Mniej więcej wygląda to tak:
class Klasa():
def jeden(self):
coś tam
def dwa(self):
coś innego
def trzy(self):
coś jeszcze innego
c = Klasa()
listaKomend = ['jeden' , 'dwa' , 'trzy']
if any(komenda in wartosc for komenda in listaKomend):
komendaDoWyk = 'c.'.join(re.findall('[a-zA-Z]+', wartosc))
komendaDoWyk()
po tym dostaje: TypeError: 'str' object is not callable
Czytając wasze wypowiedzi, zakładam że kolega @mdolata już problem rozwiązał.
Sprawdzę jak będę w domu.
PS. Sorki, trochę się pospieszyłem z postem, dodałem brakujące funkcje. PS. Nie stosuje normalnie polskich znaków, napisałem to tylko jako przykład.
Po kolei:
komendaDoWyk = 'c.'.join(re.findall('[a-zA-Z]+', wartosc))
W pewnym momencie zmienna komendadoWyk przyjmuje wartość np "c.jeden".
TypeError: 'str' object is not callable
I prawidłowo. Zmienna komendadoWyk jest stringiem a nie funkcją.
Jak by to wyglądało? "c.jeden"()?
listaKomend = ['jeden' , 'dwa' , 'trzy']
if any(komenda in wartosc for komenda in listaKomend):
komendaDoWyk = 'c.'.join(re.findall('[a-zA-Z]+', wartosc))
komendaDoWyk()
A nie da się:
listaKomend = [jeden() , dwa() , trzy()]
if any(komenda in wartosc for komenda in listaKomend):
komendaDoWyk = wartosc
c.komendaDoWyk
?
No cóż.. jest taka droga, ale należy używać bardzo rozważne: https://docs.python.org/3/library/functions.html#eval
Lepiej mapować...
Mokrowski napisał(a):
No cóż.. jest taka droga, ale należy używać bardzo rozważne: https://docs.python.org/3/library/functions.html#eval
Lepiej mapować...
Istnieje też metoda dalece lepsza od evala:
Mając obiekt c, wywołujesz na nim
getattr(c, nazwa_funkcji)
co zwraca Tobie obiekt funkcji, który możesz wywołać.
Kawałek kodu ode mnie
class C:
def my_f1(self):
return "{} {}".format(self.__class__, "function1")
def my_f2(self):
return "{} {}".format(self.__class__, "function2")
class C2(C):
pass
c1 = C()
c2 = C2()
for i in xrange(2):
function_name = "my_f{}".format(i + 1)
for n in ["c1", "c2"]:
print getattr(globals()[n], function_name)()
Serechiel napisał(a):
Po kolei:
komendaDoWyk = 'c.'.join(re.findall('[a-zA-Z]+', wartosc))
W pewnym momencie zmienna komendadoWyk przyjmuje wartość np "c.jeden".
TypeError: 'str' object is not callable
I prawidłowo. Zmienna komendadoWyk jest stringiem a nie funkcją.
Jak by to wyglądało? "c.jeden"()?listaKomend = ['jeden' , 'dwa' , 'trzy'] if any(komenda in wartosc for komenda in listaKomend): komendaDoWyk = 'c.'.join(re.findall('[a-zA-Z]+', wartosc)) komendaDoWyk()
A nie da się:
listaKomend = [jeden() , dwa() , trzy()] if any(komenda in wartosc for komenda in listaKomend): komendaDoWyk = wartosc c.komendaDoWyk
?
Tak nie mogę, bo "wartość" trzeba filtrować - są tam jeszcze inne symbole.
reptile333 napisał(a):
Kawałek kodu ode mnie
class C: def my_f1(self): return "{} {}".format(self.__class__, "function1") def my_f2(self): return "{} {}".format(self.__class__, "function2") class C2(C): pass c1 = C() c2 = C2() for i in xrange(2): function_name = "my_f{}".format(i + 1) for n in ["c1", "c2"]: print getattr(globals()[n], function_name)()
Bardzo ciekawe. Dziękuje.
Koledzy @Mokrowski @enedil - również ukłony.
Temat do zamknięcia - wykorzystałem ostatecznie metodę kolegi @mdolata.