Nazwa funkcji jako string i wywołanie

0

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,

0

A nazwa-funkcji(parametry) nie działa? Przecież raczej nie wywołujesz funkcji w cudzysłowie.

1

Zmapować

0

Można utworzyć słownik który mapuje stringa na referencje funkcji:

def f1():
  return 1

dic = {"f1": f1}
method_name = "f1"
f = dic[method_name]
f() // zwraca 1
0

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?

0

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.

0

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

?

0

No cóż.. jest taka droga, ale należy używać bardzo rozważne: https://docs.python.org/3/library/functions.html#eval
Lepiej mapować...

0
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ć.

0

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)()
0
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.

1 użytkowników online, w tym zalogowanych: 0, gości: 1