Im Master Skript Unterskripte mit ihren Veriablen verwenden

  • Ich stelle gerade ein Skript für eine Energiesparfunktion für meinen digitalen Bilderrahmen zusammen, das Geofencing über IFTTT nutzt, um auf Basis des Handys der Hausbewohner zu entscheiden, wann der Rahmen aus- und angeschaltet werden soll. Dabei sendet IFTTT eine Email an den RPi, der dann auf Basis verschiedener Bedingungen entscheidet, was gemacht werden soll.

    Eine solche Bedingung ist der Zeitpunkt des Sonnenuntergangs. Zu diesem Zeitpunkt soll der Bilderrahmen für einige Stunden anbleiben, egal ob jemand zuhause ist, oder nicht.

    Die Feststellung der Sonnenuntergangszeit habe ich auf Basis von gefundenen Snippets über PyEphem gut hinbekommen:

    Die Email Abfrage geschieht im Master Skript. Dieses wiederum soll jetzt auf den aktuellen Sonnenuntergangswert ("nextsetcet") zugreifen.
    Mein Testskript zum Aufruf sieht folgendermaßen aus:

    Code
    #!usr/bin/python
    
    
    import sunset_time
    
    
    print "next sunset:  ", nextsetcet.strftime(fmt)


    Bei der Ausführung bekomme ich dann die Fehlermeldung

    Zitat

    next sunrise:
    Traceback (most recent call last):
    File "/home/pi/frame/CheckPresence.py", line 11, in <module>
    print "next sunset ", nextset.strftime(fmt)
    NameError: name 'nextset' is not defined


    Wahrscheinlich ist es ein ganz banaler Fehler, aber ich komme gerade nicht weiter..

  • Im Master Skript Unterskripte mit ihren Veriablen verwenden? Schau mal ob du hier fündig wirst!

  • Hallo,

    das gute bei (manchen) Python-Fehlermeldung ist ja: es steht sehr explizit drin, was falsch ist :)

    In deinem Fall beschwert sich Python darüber, dass die die Variable "nextset" aufrufst, diese aber nicht definiert ist, und das ganze in Zeile 11 im genannten Skript. Da musst du mal schauen.

    Abgesehen davon sehe ich die reklamierte Zeile " print "next sunset ", nextset.strftime(fmt)" in dem von dir geposteten Quelltext nicht... Da gibt's wohl eine Differenz zwischen dem, was du hier gepostest hast und was du auf dem Raspi ausführst... :)

    Gruß, noisefloor

  • Hallo noisefloor,

    was mir sicherlich fehlt, ist ein Verständnis über das Handling von Variablen in Python. Ich lese mich da auch gerade ein, nur so eine richtig gute Seite, die mit hier ein Verständnis geben könnte, habe ich och nicht gefunden.

    Was heißt denn z.B. definieren? Und wie kann ich den Wert eine Variablen jeweils neu berechnen lassen, ohne das Skript neu zu starten? Der Sonnenuntergang ist ja ein dynamischer Wert, müßte also einmal täglich durch das Subscript berechnet werden.

  • ... Wahrscheinlich ist es ein ganz banaler Fehler, aber ich komme gerade nicht weiter..

    Eigentlich ja, aber es sind mehrere Dinge die hier zusammentreffen.

    Sieh mal die beiden Beispielprogramme p und q:

    Code p:

    Python
    #!/usr/bin/python
    
    
    print "I'm in p.py"
    print "__name__: " + __name__
    
    
    def func_in_p():
            print "This is func_in_p"

    und Code q:

    Python
    #!/usr/bin/python
    
    
    import p
    
    
    print "I'm in q.py"
    print "__name__: " + __name__
    p.func_in_p()


    Wenn ich nun q aufrufe bekomme ich folgende Ausgaben:

    Code
    framp@majestix ~/t $ ./q.py 
    I'm in p.py
    __name__: p
    I'm in q.py
    __name__: __main__
    This is func_in_p

    Warum?

    In p wird einmal der print ausgeführt wenn p aufgerufen wird und die Funktion func_in_p defininiert. In q wird p importiert. Deshalb wird der print von p ausgeführt. Die Definition der Funktion func_in_p wird vorgenommen. Deshalb kann dann in q die Funktion aufgerufen werden und liefert die print Ausgabe.

    Was ist bei Dir nicht korrekt?
    Ich gehe davon aus dass sunset_time.py Dein Py Programmname ist und Du deshalb sunset_time importierst. Warum wird dir Variable nextsetcet nicht definiert? Das liegt an der Zeile

    Code
    if __name__ == '__main__':

    . Deshalb wird der folgende Code incl der Vardefinition NUR ausgeführt, wenn Du sunset_time als Hauptprogramm aufrufst. Deshalb ist __name__ bei q == __main__, da q direkt aufgerufen wird und bei p ist __name__ der Name des Programms p. Wenn Du also diese Zeile löschst und die Einrückung des folgenden Codeblocks korrigierst sollte es funktionieren.

    Aber Du solltest das anders strukturieren: Eine Funktion (def) erstellen, die Du immer im Hauptprogramm aufrufen kannst (z.B. getNextCet), die dann immer das jeweilige Ergebnis liefert.

  • Hallo,

    sapnho: zwei durchweg empfehlenswerte Tutorials zum lernen sind:
    * das offizielle Python Tutorial: https://docs.python.org/3.4/tutorial/ für Python 3.4 (oder für 2.7: https://docs.python.org/2.7/tutorial/)
    * Lern Python the hard way: http://learnpythonthehardway.org/book/

    Bei letzterem nicht vom Namen abschrecken lassen, es ist nicht "hard" ;)

    Beide Tutorials sind auf English, was hoffentlich kein Problem ist. Aber ohne English kommst du bei Python - wie den meisten anderen Programmiersprachen auch - irgendwann nicht mehr weiter.

    Gruß, noisefloor

  • Hallo,

    Nachtrag: was ich im 1. Post geschrieben habe ist nicht ganz korrekt. Python beschwert sich, dass das _Objekt_ "nextset" nicht existiert. Was da versucht wird, ist ja, vom Objekt "nextset" die Methode "strftime()" aufrufen. Geht natürlich nicht, wenn "nextset" nicht existiert.

    Ansonsten kannst du Methoden von Objekten jederzeit aufrufen und bei Bedarf das Ergebnis immer einer Variablen zuweisen.

    Einfaches Beispiel in Python Shell (Python 3.4):

    Code
    >>> import time
    >>> def get_time():
    ...     return time.asctime()
    >>> while True:
    ...     aktuelle_zeit = get_time()
    ...     print(aktuelle_zeit)
    ...     time.sleep(10)
    ...

    Hier wird zuerst das time-Modul importiert und dann die Funktion [font="Courier"]get_time[/font] definiert, welche einfach nur die aktuelle Zeit zurück liefert.

    In der [font="Courier"]while[/font]-Schleife wird die Funktion aufgerufen, das Ergebnis (=der Rückgabewert) der Variablen [font="Courier"]aktuelle_zeit[/font] zugewiesen, und das Ergebnis ausgegeben. Und nach 10s Wartzeit läuft das ganze nochmal. Beim 2., 3., ... Durchlauf der [font="Courier"]while[/font]-Schleife wird der Variablen [font="Courier"]aktuelle_zeit[/font] jedes Mal ein neuer Wert zugeordnet.

    Gruß, noisefloor

  • So wie du das machst ist das nicht wirklich praktikabel

    Es sollte imho eher so aussehen:

    sunset_time.py:

    Python
    #!/usr/bin/python
    
    
    import sunset_time
    
    
    nextsetcet = GETnextsetcet()
    fmt = "%d-%b-%Y %H%M CET"
    print "next sunset: ", nextsetcet.strftime(fmt)

    ..wobei das immer noch nicht so schön ist, sollte aber erst mal funktionieren ;)


    PS: Deine Shebang's sind auch unvollständig. " usr/bin/python " gibt es sogesehen nicht wirklich (nur wenn man sich im Wurzelverzeichnis "/" befindet) , da fehlt ein " / " um es zum absoluten Pfad zu machen

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!