Hallo zusammen,
ich habe aktuell ein Problem mit Imports und Funktionen in Logiken. Eventuell ist es auch nur ein Verständnisproblem - ich hoffe, ihr könnt mir weiterhelfen.
Zum Verstehen des Problems habe ich ein kleines Proof of Concept Skript vorbereitet, welches im folgenden "verschlimmbessert" wird, nur damit es als Smarthomeng Logik funktioniert. Die "Versionsunterschiede" in den Skripten habe ich jeweils mit Kommentaren versehen, damit ihr gleich die Unterschiede erkennen könnt.
Aktuell laufe ich (soweit ich das raus lesen kann) auf SmarthomeNg V 1.3 - also noch eine ältere Version.
Ich bin leider noch nicht dazu gekommen es upzudaten - falls das Problem also bei neueren Versionen gelöst sein sollte wäre das mal ein Grund dazu... Eventuell kann ja jemand mit einer aktuellen Version das Skript ausprobieren, falls das nicht ganz sicher ist.
Version 1 des Poc Skriptes:
So funktioniert es theoretisch, wenn ich es einfach mit Python starte (also ausserhalb von Smarthomeng)
HTML-Code:
#/usr/local/smarthome/logics/poc.py #!/usr/bin/env python from datetime import datetime #import von datetime def func1(): today = datetime.today() sh.telegram(str(today),True) #Ausgabe von Today als String def func2(): func1() #Aufruf von func1 try: func2() #Aufruf von func2 except Exception as e: sh.telegram(str(e),True) #Fehlerausgabe
Func1 holt sich aus datetime das heutige Datum und gibt es via sh.telegram Plugin einem Telegram Bot aus. Ich verwende hier sh.telegram mal als Synonym für die Python eigene print Funktion. Geht hier also lediglich um die Textausgabe!
Func2 ruft Func1 auf.
Im Try Block wird Func2 aufgerufen, bei einem Fehler bekomme ich die Fehlermeldung als Text ausgegeben.
Dieses Skript funktioniert nun also in der normalen cli, wenn ich es mit Python starte (wenn sh.telegram = print!)
Als Smarthomeng Logik funktioniert es nicht. Stattdessen bekomme ich folgenden Fehler:
HTML-Code:
name 'func1' is not defined
Version 2:
Ich gebe nun Func1 als Parameter für Func2 mit, damit Func2 Func1 kennt
HTML-Code:
#/usr/local/smarthome/logics/poc.py #!/usr/bin/env python from datetime import datetime def func1(): today = datetime.today() sh.telegram(str(today),True) def func2(f): #func2 bekommt nun eine Funktion als Parameter f() #und ruft diese Funktion auf try: func2(func1) #hier wird func1 als Parameter mitgegeben. Denn hier kennt man func1 except Exception as e: sh.telegram(str(e),True)
HTML-Code:
'module' object has no attribute 'today'
Version 3:
Nun gebe ich den Import in der Funktion mit. Das würde dafür sorgen, dass er plötzlich das sh Objekt nicht kennt (da ich das bisher auch nicht mitgegeben habe). Deshalb ziehe ich auch das sh Objekt via Parameter in den Kontext der Funktionen.
HTML-Code:
#/usr/local/smarthome/logics/poc.py #!/usr/bin/env python def func1(sh): #sh wird mitgegeben from datetime import datetime #import wurde in func1 gezogen today = datetime.today() sh.telegram(str(today),True) def func2(f,sh): #funktion und sh werden mitgegeben f(sh) try: func2(func1,sh) #funktion und sh werden mitgegeben except Exception as e: sh.telegram(str(e),True)
HTML-Code:
2020-02-04 10:36:04.380120
Nun meine Frage.
Gibt es einen besseren Weg, Funktionen und Imports in den Kontext von Funktionen zu ziehen?
Wenn ich ein großes Skriopt mit vielen Funktionen habe, die innerhalb von Funktionen aufgerufen werden (die auch innerhalb von Funktionen aufgerufen werden usw.)
Dann müsste ich immer via Parameterangabe die ganzen Funktionen mit geben, nur damit sie innerhalb von Funktionen genutzt werden können!
Man erkennt schon am Satz, dass das ein großer Sche** ist...
Da kann ich ja komplett auf Funktionen verzichten und einfach eine Prozedur schreiben - wenn ich den gleichen Code nochmal brauche mach ich halt Copy&Paste.
Also, hat jemand schon Erfahrungen damit gemacht und eine saubere Lösung für Imports und Funktionen in Funktionen - in Logiken?
Merci, ich hoffe, ich konnte das Problem einigermaßen verständlich erklären.
Kommentar