An die python cracks. Hilfe bei Minidisplay.

  • Aaah, ok...dann halt so:

    Ausgabe

    Code
    0
    1
    1

    Somit habe ich den Wert überschrieben und (natürlich) auch keine Fehlermeldung bekommen. Irgendwo meine ich mal gelesen zu haben, dass man sich schon sehr sicher sein muss, wenn man "global <variable" verwendet.

  • Irgendwo meine ich mal gelesen zu haben, dass man sich schon sehr sicher sein muss, wenn man "global <variable" verwendet.

    Deswegen nimmt man solche Konstrukte mit globalen Variablen nicht gerne. Bei kleineren Skripten kann das durchaus Sinn machen, bei größeren Projekten wird es dann aber sehr schnell unübersichtlich, da man nie weiß, welche Funktion wann und wo was überschreibt. Du kannst also ganz andere Werte erhalten, als Du eigentlich erwartest. Eine Fehlermeldung gibt es auch nicht, da es ja kein Syntax-, sondern ein logischer Fehler im Programmablauf ist. Das sind die gemeinsten Fehler ;)

    AZi (DEV): Nexus auf LibreElec | Asrock J4205 | 4 GB RAM | 128 GB Sandisk| Rii mini
    DEV: PC Ubuntu 20.04 | Matrix
    AZi: Tanix TX3 | Android/CoreElec Dualboot (EMMC), Nexus
    WoZi: Nexus auf LibreElec | Asrock J4205 | 4GB RAM | 128 GB Sandisk SSD | Atric IR | URC7960

    NAS: unRaid, 3x6TB, 2x12TB | TV-Server: Futro S550 mit Hauppauge QuadHD DVB-C
    PayPal: paypal.me/pvdbj1

  • @DaVu du bist ja gut, zitierst mein erstes Beispiel und änderst die wichtigste Stelle :thumbup: LOL

    An globalen Variablen ist nichts magisches, man muß nur wissen, dass, sofern man den Code nicht 100%ig in eigener Hand hat,
    sich der Wert dieser unvorgesehen ändern kann. Solange Du deinen Code bei Dir in deiner Umgebung laufen lässt, ist es raltiv sicher.
    Voraussetzung natürlich, Du behandelst die globale Variable auch so wie vorgesehen.

    @tjost
    ich bin nicht wirklich tief in der Kodi Thematik drin, heisst ich schaue auch in die Doku.
    Ich MEINE verstanden zu haben, dass z.B. über die Monitor Klasse Events abgefangen werden können welche
    Dir den Hinweis geben was gerade bei Kodi passiert. Wenn Du mir kurz zusammenschreiben kannst, was Du
    genau wann, wie haben willst, schaue ich mir das gerne heute Abend/Nacht an und gebe Dir Bescheid.

    Bezgl. des aktuellen Problems

    vor der while not xmbc.Monitor().waitForAbort Zeile fügst Du zum Beispiel eine Variable

    status = False

    ein.

    In deinem Code würdest Du dann folgendes machen

    Python
    if window=="10000":
        status = not status
        if status: # im Falle von True
            create_and_display_image(systemday, systemdate, font28)
        else: # im Falle von False
            create_and_display_image(systemtime, systemdate)

    Keine sleeps innerhalb der if-Bedienung notwendig, da du bei jedem Schleifendurchlauf einen anderen Wert setzt.
    Also,
    initialer Wert von Status ist False
    Erster Durchlauf
    status = not status erzwingt das aus False nun True wird
    damit wird if status ausgefüht-
    Nächster Durchlauf, status ist immer noch auf den Wert True gesetzt,
    erzwingt nun status = not status das der Wert wieder auf False gesetzt wird und daher nun
    der else Teil ablaüft. Beim nächten wieder der if Teil und so weiter.

    Wenn Du noch aus waitForAbort(2) ein waitForAbort(5) machst, hast Du deine 5 Sekunden Wartezeit.

    Ginge das?

    Cheers
    Claudia

  • also, ich habe das mal getestet:

    Code
    status = not status
                                                UnboundLocalError: local variable 'status' referenced before assignment

    Diese Fehlermeldung bekomme ich.

    Nun da die Adafruit Library ja etwas beschränkt ist und ich z.B. keine Laufschrift erzeugen kann dachte ich es wäre nett wechselnden Text zu verwirklichen.
    Alles andere funktioniert aktuell ja.

    Wenn ich das ganze in eine def setze und nur die def aufrufe würde das eher gehen?

    wenn ich

    while not xbmc.Monitor().waitForAbort(1): auf 5 setze dann bremst das die Aktualisierung aller Anzeigen beim erneuten durchlaufen aus.

  • Das ist genau die Fehlermeldung die Du bekommst wenn Du eine global Variable in einer Funktionen ändern willst - das Thema global Variable!
    Also vor

    status = not status

    ein

    global status

    also

    global status
    status = not status


    Wie das alles in deinem Code aussieht, kann ich nicht sagen ohne den zu sehen.
    Aber generell gesagt ist es egal ob Du in der while not ... 5 Sekunden wartest oder innerhalb der Schleife ein 5 Sekunde Wartezeit hast.

    Cheers
    Claudia

  • also jetzt habe ich es so ziemlich.
    ich habe jetzt
    global status
    status = False
    vor das

    while not xbmc.Monitor().waitForAbort(1):
    ind die schleife als Wert dann
    status = not status
    im Code dann das und es funktioniert soweit.

    Python
    if window=="10000":
    		def status1():
    			if status:
    				create_and_display_image(systemday, systemdate, font28)
    				xbmc.sleep(5000)
    			else:
    				create_and_display_image(systemtime, systemdate)
    				xbmc.sleep(5000)
    			pass
    		status1()
  • Das funktioniert?
    Wenn dann aber nicht aus den von Dir genannten Gründen.

    Edit: verstehe, vermute das status = not status steht direkt innerhalb der while schleife und nicht in einer Funktion, ok,
    dann braucht es aber das global status nicht.


    Und darf ich frage wieso Du das mit dem

    Python
    def status1():
        Code ....
        ....
    
    
    status1()


    machst? Was bringt Dir das? Wird die Funktion status1 noch des öfteren aus anderen Codeteilen aufgerufen?

    Cheers
    Claudia

  • ne ne das geht auch ohne das def.

    ich hatte vorher Fehlermeldungen das er die nächste Zeile das "elif ..." ein ungültiger Wert sei.
    Also hatte ich das in ein def gesetzt so wie ich gelesen und verstanden hatte.
    Nun habe ich es glaube ich verstanden.

    1. ich hatte aus dem Thread hier den Code per Copy und Paste in Textwrangler eingebunden dabei hatte er warum auch immer format Fehler fabriziert die ich nicht nachvollziehen konnte. Erst durch Neueingabe ohne Copy und Paste funktioniert es.
    2. ich habe dadurch angenommen das ich innerhalb einer if-elif Schleife nicht direkt eine 2 einsetzen könnte. Darum dachte ich das dies eine Lösung sei. Nun bin ich wieder etwas Schlauer.

  • Formatfehler klingt nach einem Mix aus Tabs und Spaces beim Einrücken.
    Meine Beispiele habe ich immer mit Spaces gepostet. Du verwendest wahrscheinlich Tabs zu einrücken, oder?
    Da ist Python ziemlich kleinlich aber verständlich da darüber ja der Codeblock erkannt wird.

    Best practice - immer nur eine Variante wählen, entweder Tabs oder Spaces.
    Textwrangler hat doch bestimmt eine Einstellung wo du das erzwingen kannst, oder?

    Cheers
    Claudia

  • Das würde ich so nicht unterschreiben:


    Wie würdest Du dann erklären das eine Variable, die ausserhalb einer Funktion definiert wurde,
    innerhalb der Funktion gelesen werden kann?
    Wenn es stimmen würde, das alle Variablen innerhalb einer Funktion lokale Variablen sind, dann darfst Du dies nicht machen können

    Code
    x=42
    
    
    def test():
        print x

    Es müsste ein Fehler beim Ausführen der Funktion test kommen, dass die Variable x keinen Wert hat oder nicht initialisiert ist.

    Cheers
    Claudia

  • Ich habe versucht mich gersten noch ein wenig einzulesen, wollte dann hier noch antworten, wollte aber den Thread nicht zu sehr offtopic gehen lassen um es @tjost nicht zu erschweren seine Lösung zu finden ;)

    Da du es aaber gerade ansprichst @ClaudiaF ;) ...

    Ich gebe zu, dasss ich "implizit" missverstanden habe.

    Vielleicht verstehe ich es auch komplett falsch und dann erleuchte mich bitte.

    Ich versuche deinen Code mall zu erleutern, so wie ich ihn verstehe und erstelle dann ein eigenes Beispiel

    In deinem letzten Codebeispiel weißt du x die Zahl 42 zu und machst sie somit zu einer "globalen" Variable, die natürlich auch der Funktion "Test" zur Verfügung steht. Somit kommt es beim Aufruf der Funktion natürlich auch zu keinem Fehler und die Zahl 42 wird ausgegeben.

    Nehmen wir jetzt aber mal:

    Python
    #!/usr/bin/python2
    
    
    def funk():
    	glo_var = 1
    	print glo_var
    
    
    funk()
    print glo_var


    In dem Fall erstelle ich eine Funtkion und habe in dieser Funktion eine "lokale" Variable. Diese Variable wird auch ausgegeben sofern ich die Funktion aufrufe. Versuche ich die Variable außerhalb der Funktion aufzurufen, bekomme ich eine Fehlermeldung. Die Ausgabe des obigen Scripts sieht also wie folgt aus:

    Code
    davu@Ubuntu-Desktop:~/testing$ ./global.py 
    1
    Traceback (most recent call last):
      File "./global.py", line 8, in <module>
        print glo_var
    NameError: name 'glo_var' is not defined

    Es wird zuerst die "1" ausgegeben, weil ich die Funktion zuerst aufgerufen habe. Soweit so gut. Als ich aber dann versuche die Variable außerhalb der Funktion aufzurufen, kommt es zu der Meldung, dass "glo_var" nicht definiert wurde.

    Wenn alle Variablen immer global sind, wie erklärst du es dann, dass eine Variable, die innerhalb einer Funktion deklariert wurde, nicht außerhalb einer Funktion gelesen werden kann?

    Ich lasse mich gern ohrfeigen, wenn ich die Worte "global" und "lokal" falsch interpretiere. Dann berichtige mich bitte. So wie ich das aber verstehe, sind variablen, die ich "ausschließlich" innerhalb einer Funktion definiere, lokal, und außerhalb einer Funktion global. Wenn das, was ich hier sage, falsch ist, dann müssen die das hier auch berichtigen:

    https://www.python-kurs.eu/python3_global_lokal.php


  • Wenn alle Variablen immer global sind, wie erklärst du es dann, dass eine Variable, die innerhalb einer Funktion deklariert wurde, nicht außerhalb einer Funktion gelesen werden kann?

    Variablen, die innerhalb einer Funktion definiert werden, sind per se lokal, also ausserhalb nicht bekannt (es sei denn, sie werden innerhalb der Funktion als global definiert). Soweit richtig. Variablen, die ich außerhalb einer Funktion und noch vor dem Funktionsaufruf deklariere, gelten auch innerhalb der Funkton, sind also implizit global.

    Code
    teiler = 2
    
    
    def division(x):
        return x / teiler
    
    
    print division(42), ' ist auch nur die halbe Warheit'

    AZi (DEV): Nexus auf LibreElec | Asrock J4205 | 4 GB RAM | 128 GB Sandisk| Rii mini
    DEV: PC Ubuntu 20.04 | Matrix
    AZi: Tanix TX3 | Android/CoreElec Dualboot (EMMC), Nexus
    WoZi: Nexus auf LibreElec | Asrock J4205 | 4GB RAM | 128 GB Sandisk SSD | Atric IR | URC7960

    NAS: unRaid, 3x6TB, 2x12TB | TV-Server: Futro S550 mit Hauppauge QuadHD DVB-C
    PayPal: paypal.me/pvdbj1

  • Und genau das ist das, was ich damit sagen wollte. Es kommt drauf an, wo ich sie definiere.

    Variablen sind nicht 'grundsätzlich' implizit global.

    Wenn ich eine globale Variablen habe (nennen wir sie 'x' mit Zuweisung "1") und dann innerhalb einer Funktion der Variablen 'x' einen anderen Wert zuweise (der nur lokal in der Funktion gültig ist) und vor aber noch "global x" I'm Script have, dann habe ich den Wert der globalen Variablen überschrieben.

    Nicht mehr und nicht weniger wollte ich damit sagen ;)

  • >Variablen sind nicht 'grundsätzlich' implizit global.

    Doch.

    Mein Zitat:
    Variablen sind grundsätzlich implizit global, erst wenn eine Zuweisung erfolgt könnte aus einer globalen Variable
    eine lokale werden.

    Solange eine Variable in einer Funktion keine Zuweisung bekommt, gibt es diese nicht im locals sondern nur
    im globals. Damit ist sie wie BJ1 richtig sagt, implizit global, weil ja nirgends im Code explizit ein global gesetzt wurde.

    Beispiel das hoffentlich auch zeigt warum und wo darauf zu achten ist:

    Beim Aufruf von der Fuktion t wird folgendes ausgegeben


    locals:{}
    globals:42

    Zuweisung erfolgt

    locals:{'x': 12}
    globals:42

    Solange keine Zuweisung gemacht wurde existiert nur eine Variable x, nach der Zuweisung
    existieren 2 Variablen x, eine lokale und eine globale.

    Den Aufruf globals()['x'] habe ich gemacht, damit x gefiltert wurde, kann natürlich auch mit globals()
    aufgerufen werden, dann bekommt man alle, zur Laufzeit bestehenden Objekte im globals zurückgeliefert.

    Und das Beispiel zeigt hoffentlich auch warum das so wichtig ist. Greife ich in einer Funktion
    auf eine Variable zu, die erst später in der Funktion, durch eine Zuweisung, lokal definiert wird, habe
    ich wahrscheinlich ein unerwünschtes Verhalten.

    Cheers
    Claudia

  • Variablen sind grundsätzlich implizit global, erst wenn eine Zuweisung erfolgt könnte aus einer globalen Variable
    eine lokale werden.

    Das stimmt. Aber auch nur dann, wenn ich sie global definiere.

    Wenn ich eine Variable aber ausschließlich innerhalb einer Funktion (und gar nicht außerhalb) definiere ist es auch ausschließlich eine lokale Variable:


    y taucht ausschließlich als lokale Variable auf, da ich sie auch nur lokal in der Funktion definiert habe. Ich habe die Filterung von "x" mal rausgenommen, damit auch wirklich alle globals angezeigt werden und es deutlich wird, dass "y" dort nicht auftaucht.


    Code
    davu@davu-Laptop2:~/testing$ ./locales2.py 
    locals:{'y': 12}
    globals:{'__builtins__': <module '__builtin__' (built-in)>, '__file__': './locales2.py', '__package__': None, 't': <function t at 0x7fe74b4675f0>, 'x': 42, '__name__': '__main__', '__doc__': None}

    ^^ wie du siehst, kein "y" unter globals


    Solange ich also eine Variable nicht global definiere, ist sie offensichtlich auch nicht.

    Von daher sage ich immer noch, dass Variablen nicht immer und per se global sind. Es kommt darauf an, wo ich sie definiere. Wenn ich sie nicht in einer Funktion definiere, dann ist sie global (und das immer..da gebe ich dir Recht). Definiere ich sie aber nicht außerhalb einer Funktion, sondern nur innerhalb einer Funktion, dann ist sie lokal (und das ausschließlich). Sie wird erst zu einer globalen Variablen, wenn ich sie mit "global <variable" als globale Variable definiere.

    Das gleiche sagt ja auch @BJ1 mit:

    Variablen, die innerhalb einer Funktion definiert werden, sind per se lokal, also ausserhalb nicht bekannt (es sei denn, sie werden innerhalb der Funktion als global definiert).


    Weiter sagt er natürlich, was auch richtig ist:

    Variablen, die ich außerhalb einer Funktion und noch vor dem Funktionsaufruf deklariere, gelten auch innerhalb der Funkton, sind also implizit global.

    Von daher, zu sagen, dass Variablen immer global sind, ist einfach nicht richtig. Das entscheidet doch der Programmierer, ob es eine lokale oder globale Variable ist, je nachdem ob er sie ausschließlich innerhalb oder außerhalb der/einer Funktion definiert.

    Gruß
    DaVu

    Einmal editiert, zuletzt von DaVu (23. Januar 2018 um 22:45)

  • Ich glaube jetzt weiß ich wo dein Mißverständnis ist, schau Dir mal folgendes an

    Python
    def t():
        y
    t()
    Traceback (most recent call last):
      File "<input>", line 1, in <module>
      File "<input>", line 2, in t
    NameError: global name 'y' is not defined

    y ist nicht definiert und wo wurde es gesucht, im globals dictionary.

    Durch deine Zuweisung von

    y = 12

    wurde aus einer implizit globalen Variable eine explizite lokale Variable.

    Implizit heisst, dass wenn nicht explizit defniert wird eine globale Variable angenommen wird.
    Die Zuweisung y = 12 innerhalb der Funktion ist eine explizite Anweisung eine lokale Variable zu
    erstellen, WENN nicht vorher innerhalb der Funktion ein global explizit eine globale Variable definiert hatte.

    Cheers
    Claudia

  • Ok, ich hätte jetzt vermutet, dass das ein Syntax-Fehler ist. Warum in aller Welt soll ich denn eine Variable nennen und dieser nichts zuweisen. Das macht doch gar keinen Sinn. Das sowas bei C++ gemacht wird kenne ich. Da weise ich mit int a der Variablen einen Typen zu (integer), aber noch keinen Wert. Bei Python bestimmt doch wie der Inhalt/Wert einer Variablen zugewiesen wird, um welchen Typen es sich handelt und somit hat sie auch gleichzeitig einen Wert.

    Python
    a = 2
    b = "2"
    
    
    type(a)
    type(b)


    Wenn einer Variablen in Python kein Wert zugewiesen wird, ist das immer ein Fehler. Egal ob ich es innerhalb oder außerhalb einer Funktion geschieht. Somit muss ich in Python einer Variablen immer einen Wert zuweisen und dann entscheidet es sich auch, ob die Variable global oder lokal ist.

    Ein Script mit:

    Python
    #!/usr/bin/python2
    x

    erzeugt bei der Ausgabe:

    Code
    davu@davu-Laptop2:~/testing$ ./locales.py 
    Traceback (most recent call last):
      File "./locales.py", line 2, in <module>
        x
    NameError: name 'x' is not defined


    Ich muss also "x" definieren und dann würde es in dem Fall (weil keine Funktion) eine Globale Variable sein.

    Hierbei

    Python
    #!/usr/bin/python2
    
    
    def t():
       x = 32
       print x
    
    
    t()
    print x

    ist "x" ausschließlich eine lokale Variable und global nicht verfügbar, was man am "print x" außerhalb der Funktion deutlich sehen kann:

  • Der NameError hat doch aber nichts mit unserer Diskussion zu tun, sondern diente nur der Klarstellung,
    nämlich der das der Python Parser davon ausgegangen ist, dass y eine globale Varibale sein müsste,
    das er diese dann aber nicht gefunden hat führte zur Exception.

    Übrigens, ist das durchaus ein Mittel was benutzt wird, zum Beispiel um zu sehen ob Objekte
    bereits initialisiert wurden oder nicht. Im Sinne von

    Code
    try:
        x
    except NameError:
        ... hier das was zu tun ist, wenn x noch nicht definiert ist.


    Cheers
    Claudia

  • Gut...richtig...

    Der Name error in diesem Beispiel:

    zeigt aber doch ziemlich deutlich, dass "x" ausschließlich lokal verfügbar ist.

    Ich starte das Script, der Wert "32" wird "x" durch den Aufruf der Funktion in Zeile 6 ausschließlich lokal zugewiesen und dann auch innerhalb der Funktion mit dem print-Befehl und dem Ergebnis "32" ausgegeben

    Danach rufe ich mit einem weiteren print-Befehl wieder "x" auf, welches nicht in der Funktion ist. Die Fehlermeldung sagt, dass "x" nicht definiert wurde und man sieht, dass wohl nach einer globalen Variable gesucht wird, die nicht vorhanden ist. Anhand des Bespiels kannst du doch wirklich nicht sagen, dass Variablen immer global sind. Sie können offensichtlich auch ohne weiteres ausschließlich lokal sein. denn ohne den print-Befehl in Zeile 7 läuft das Script fehlerfrei durch.

  • Wenn Du jetzt zwei "Xe" definierst (eines aussen, das andere innerhalb einer Funktion), sind sie trotzdem voneinander unabhängig, obwohl sie gleich heissen.

    AZi (DEV): Nexus auf LibreElec | Asrock J4205 | 4 GB RAM | 128 GB Sandisk| Rii mini
    DEV: PC Ubuntu 20.04 | Matrix
    AZi: Tanix TX3 | Android/CoreElec Dualboot (EMMC), Nexus
    WoZi: Nexus auf LibreElec | Asrock J4205 | 4GB RAM | 128 GB Sandisk SSD | Atric IR | URC7960

    NAS: unRaid, 3x6TB, 2x12TB | TV-Server: Futro S550 mit Hauppauge QuadHD DVB-C
    PayPal: paypal.me/pvdbj1

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!