[Python3] for - Loop

  • Ich bin gerade etwas irritiert bei folgenden Code:

    Code
            # Read raw values into bytearray buffer.
            buffer = bytearray()
            for _ in range(10):
                item = self.bus.read_byte(self.address)
                buffer.append(item)

    Und zwar über den Unterstrich in for _ in. Man kann also ein x-beliebiges Zeichen als Zählervariable nutzen?

    Die Quelle: https://github.com/daq-tools/rpi-piusv Datei: rpi_piusv.py

    Und ist dann ziemlich hinterhältig weil einem der Unterstrich kaum auffällt.

    Geht auch ein Leerzeichen? :)

    MfG

    Jürgen

    Edit:

  • Die Schleife sagt ja für "nichts" (_) 10 mal durchlaufen. Mehr ist da nicht. Was willst Du damit machen?

    //Edit Das ist einfach nur eine Schleife, die 10 mal rennt.

    //Edit2 Normal wäre hier ein i für item an Stelle von _ angebracht.

  • Das ist ein Scipt das die PIUSV+ ausliest. Ich hatte das erstmal als Vorlage/Beispiel.

    Bis jetzt hab ich ein Python2-Script RE: Pi USV+ Monitoring Script (modifiziert) zum auslesen benutzt.

    Ich wollte das nur in Python3 wiederhaben/konvertieren, weil ich damit die PIUSV+ überwachen kann.

    Die Printanweisungen hab ich schon angepasst, im Moment hänge ich an den for-Schleifen fest, genauer an

    for i in range (self.data_2/2): Das 2/2 ist wohl ein (in Basic) Step 2.

    Da bin ich noch am suchen.

    MfG

    Jürgen

  • for i in range (self.data_2/2):

    Mühsam ernährt sich das Eichhörnchen im Frühjahr

    for i in range (self.data_2, 2):

    MfG

    Jürgen

  • Hallo,

    'self.data = 10' und so wie ich das gesehen habe wird das im Skript auch nicht geändert. (Habs nur überflogen)

    In Python2 wird mit for i in range(self.data_2/2): der "Inhalt" von 'self.data_2' durch 2 geteilt, damit läuft die Schleife in dem Fall 5 mal durch.

    Unter Python3 funktioniert das so nicht und auch for i in range(self.data_2, 2): ist, wie schon gesagt, falsch. Hier wäre 'self.data_2' der Startwert und '2' der Endwert, bis zu dem gezählt wird.

    Wenn du die Logik so beibehalten willst, dann musst du 'self.data_2' das bis jetzt noch vom Typ 'float' ist in einen 'integer' wandeln.

    Code
    for i in range(int(self.data_2 / 2)):
        print(i)


    Grüße

    Dennis

    Edit:

    Noch etwas zu der Schleife und den Namen:

    Code
    for _ in range(5):
        print('Es wird fünf mal etwas ausgeführt')
    
    for number in range(5):
        print(f'number wird jetzt benutzt und hat in diesem Vorgang den Wert: {number}')
    
    for number in range(5, 10):
        print(f'number wird jetzt benutzt und hat in diesem Vorgang den Wert: {number}')

    'for' beschreibt die Schleife, der Name danach wird an den Wert gebunden der 'range' ausgibt. Man hat sich darauf geeinigt, das wenn man den Wert nicht benötigt keine unnötigen nichtssagende Namen verwendet, sondern einfach einen Unterstrich. Jeder der die Zeile liest, weis dann schon genau, dass mit dem Wert nichts weiteres passiert.

    Anders ist es, wenn man den Wert verwenden will, dann sollte man aussagekräftige Namen verwenden bzw. die üblichen Zählvariablen die auch in der Mathematik verwendet werden.

    Lass mal den Beispielcode laufen, vielleicht hilft das zum Verständnis.

    🎧 With the music execution and the talk of revolution, it bleeds in me and it goes 🎧

    Einmal editiert, zuletzt von Dennis89 (19. Dezember 2021 um 11:16)

  • Der _ ist eine Konvention für einen Namen, der nicht genutzt wird.

    In der REPL wird dem _ immer das letzte Objekt zugewiesen, dass keinem Namen zugeordnet worden ist.

    Jedenfalls ist das ein ziemlich umständlicher Weg 10 Bytes zu lesen.

    Code
            # Read raw values into bytearray buffer.
            buffer = bytearray()
            for _ in range(10):
                item = self.bus.read_byte(self.address)
                buffer.append(item)

    Das ist wahrscheinlich smbus geschuldet. Es gibt keine Methode, um mehrere Bytes zu lesen, ohne vorher ein Register zu beschreiben.

    Könnte man als List-Comprehension Generator-Expression kürzer schreiben:

    Code
    buffer = bytearray(self.bus.read_byte(self.address) for _ in range(10))
  • Erstmal Danke für die ganzen Erklärungen, das hat mir weitergeholfen.

    Mittlerweile habe ich mein altes Script auf Python3 umgestellt.

    Ich bin noch am überlegen wie ich das lesefreundlich verpacke.

    Ist schon ein Weilchen her das ich das mal angepackt hatte.

    Ich hab schon Bücher über Python3, aber das mit den  _ steht da nicht drin.

    Es geht um die PIUSV+. Ich habe ein neues Monitorprogramm gefunden,

    das zum einen kompatibel zum alten Programm von CW2 ist, aber in den Sourcen vorliegt.

    Unter Bullseye64 läuft es schonmal, unter Buster64 ließ es sich zumindestens schonmal kompilieren,

    aber da ist noch keine USV dran (Keine Akkus mehr).

    Aber damit kann man dann die PIUSV+ auch am RPi4B weiterbetreiben und muss sie nicht entsorgen.

    Das Pythonscript ist für die Überwachung der PIUSV+. Damit erzeuge ich Grafiken mittels SNMP/MRTG.

    Jetzt bin ich am überlegen ob ich noch Influxdb/Grafana mit einbinden kann.

    MfG

    Jürgen

  • Hallo,

    Ich bin noch am überlegen wie ich das lesefreundlich verpacke.

    Du könntest dich zum einen an den Python Style-Guide halten. Ordentliche Namen machen schon einiges aus und man vermeidet störende Kommentarzeilen. Namen in der '__init__' der Klasse erstellen und nicht irgendwo in einer anderen Funktion, Wenn von einem Wert immer nur die Hälfte gebraucht wird, dieser nicht verändert wird, dann könnte man Konstanten dafür einführen. Eine Liste mit zehn Nullen zu erstellen kann man auch einfacher machen: zehn_nullen = [0] * 10. f-Strings könnte man verwenden, wenn Exceptions nicht behandelt werden ('err') muss man sie auch nicht aufzählen und nackte 'except' verwendet man eig auch nicht. Naja und so weiter eben :geek:


    Ich hab schon Bücher über Python3, aber das mit den _ steht da nicht drin.

    Dafür findest du es in der Python Dokumentation, wenn auch nur in einem Satz:

    It is also commonly used for unused variables.

    Grüße

    Dennis

    🎧 With the music execution and the talk of revolution, it bleeds in me and it goes 🎧

  • Jürgen Böhm Ich verstehe die Verwunderung nicht ganz das `_` als Variablenname geht. Regeln für Variablennamen sind „darf nicht mit Ziffern anfangen und ansonsten beliebige Buchstaben und Ziffern und _ enthalten“. Der Unterstrich ist keine Ziffer, und Du hast den bestimmt schon in Namen gesehen, und auch am Anfang von Namen ist der in Python nix besonderes. Was genau spräche also gegen die Vermutung, dass ein `_` genau wie ein einzelner Buchstabe wie `i` ein normaler, gültiger Name ist?

    Und in sehr vielen anderen verbreiteten Programmiersprachen ist das auch ein gültiger Name. C, C++, Java, JavaScript, …

    Das man den Unterstrich nicht so sieht ist ja gerade gewollt, weil der Wert dahinter ja auch nirgends verwendet wird. Darum wählt man den als Namen, weil der ganz gut ausdrückt, „Name egal, wird nicht verwendet“. Wenn man da einen auffälligeren Namen gewählt hätte, wie beispielsweise `i`, wäre ja die nächste Frage vom Leser gewesen, warum wird der nirgends verwendet, ist das ein Fehler, oder der Code noch unfertig? IDEs und Linter meckern unbenutzte Namen in der Regel auch an. Dann muss man entweder mit einer Warnung leben oder auch noch einen Kommentar dran schreiben für den Linter, dass er das ignorieren soll. Damit lenkt man dann noch mehr Aufmerksamkeit vom Leser auf einen Namen der gar nicht benutzt wird.

    Diese Konvention ist deutlich älter als Python 3. Ich vermute mal die wurde von Haskell übernommen als die „list comprehension“-Syntax in Python 2 eingeführt wurde, denn in Haskell ist das nicht nur Konvention, sondern muss auch vom Compiler unterstützt werden, weil die Sprache statisch typisiert ist und man `_` auch für mehr als einen Wert mit unterschiedlichen Typen benutzen kann und beim „pattern matching“ steht `_` für jeden beliebigen Wert. Wie auch in Python 3.10, wo es in dem Zusammenhang zur Syntax gehört.

    “Dawn, n.: The time when men of reason go to bed.” — Ambrose Bierce, “The Devil's Dictionary”

  • Ich verstehe die Verwunderung nicht ganz das `_` als Variablenname geht.

    Die Erklärung ist einfach, ich kannte das bisher nicht.

    Und der Unterstrich war mir erstmal garnicht aufgefallen, da ich die Sourcen mit less im Terminal angesehen hatte.

    Jetzt bin ich etwas schlauer.

    MfG

    Jürgen

Jetzt mitmachen!

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