Funktionsaufruf aus Variable

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
HeAdLeSs
User
Beiträge: 22
Registriert: Dienstag 8. März 2016, 09:22

Hallo zusammen.

Ich möchte eine Funktion 'dynamisch' aufrufen. Die Kommandos sind in einer Datenbank gespeichert.
Dabei muss auch noch evtl. ein Modul eingebunden werden.

Als Beispiel.
In der Datenbank steht das Commando 'foo.bar()'
foo.bar() muss jetzt ausgeführt werden. Nur wie?

Mein Ansatz:

Code: Alles auswählen

    func = crontab["ct_Command"]
    func_mod = func.split(".")
    if len(func_mod) > 1:
        func_mod[0] = imp.load_source(func_mod[0], '/home/pi/bob/modules/'+func_mod[0]+'.py')

    print eval(func_mod[0].func_mod[1])
Dabei bekomme ich den Fehler "TypeError: 'unicode' object is not callable". Logisch. Nur wie mache ich aus einem Unicode String eine 'Funktion'?

Ich habe auch versucht:

Code: Alles auswählen

    func = crontab["ct_Command"]
    func_mod = func.split(".")
    if len(func_mod) > 1:
        func_mod[0] = imp.load_source(func_mod[0], '/home/pi/bob/modules/'+func_mod[0]+'.py')

    func()
Ging aber auch nicht.

Kann mir bitte jemand helfen. Danke.
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

@HeAdLeSs: der Ansatz ist schon falsch. Wie viele Module hast Du denn? Kommen, während das Programm läuft weitere Module hinzu? (Wenn ja, warum?) Was sind das für Kommandos? Was steht in den Modulen?
HeAdLeSs
User
Beiträge: 22
Registriert: Dienstag 8. März 2016, 09:22

Hallo Sirius3.

Ich würde keine feste Zahl angeben. Das gesamte Programm ist recht umfangreich. Aktuell ca. 15 Module.
Dieser Teil ist soetwas wie ein Cron-Taskmanager. Das Python Script wird jede Minute vom System-Crontab aufgerufen und soll dann seinerseits schauen ob es etwas zu tun gibt. Deswegen ist es in einer Datenbank hinterlegt. Dort steht dann die nächste Runtime und ein Kommando. Dieses kann ein Shell Kommando sein oder der Aufruf einer Funktion innerhalb der Software.

Shell Kommando ist recht einfach. Das Problem hier ist halt der Aufruf der entsprechenden Funktion innerhalb des Programms. Diese Funktion steckt meist innerhalb eines Moduls. Deswegen muss das erst einmal Importiert werden. Damit dann die Funktion aufgerufen werden kann. (Soweit zumindest mein Gedankengang.)

In den Modulen sind dann verschiedenste Funktionen definiert. Alles mögliche. Von Sensor-Auslesungen bis zu Soundsteuerung.
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

@HeAdLeSs: wie Sirius3 schon schrieb: der Ansatz ist falsch. Ein anderer wäre, alle aufzurufenden Services mit einem command-line Interface zu versehen. Dann kannst Du diese über externe Programme erreichen und wie normale System-Tools ausführen.
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Spricht etwas dagegen, eine Abbildung von Schluesseln auf Funktionen anzulegen, die dann per DB-Key benutzt wird?

Code: Alles auswählen

import module_a
import module_b 
import module_c

FUNCTION_MAPPING = {
    "do_a" : module_a.func,
    "do_b": module_b.something,
    ....
    }
Dann steht in der DB halt d_a.

Wann immer du versucht bist, exec oder eval zu benutzen findet sich ueblicherweise ein alternativer, weniger riskanter und eleganterer Weg.
Antworten