Seite 2 von 3
Re: Globale Namen definieren ???
Verfasst: Montag 26. Mai 2014, 18:45
von Sirius3
Warum nimmt `ControlAPairOfPins` Strings, wenn Du doch sowieso wieder alles in Ints umwandelst?
Das ganze ließe sich noch kürzer schreiben, wenn man statt der if-Abfragen direkt die Bedingung als Parameter einsetzt:
Code: Alles auswählen
def ControlAPairOfPins(FirstPin,FirstState,SecondPin,SecondState):
GPIO.output(int(FirstPin), FirstState == "1")
GPIO.output(int(SecondPin),SecondState == "1")
als nächstes solltest Du Dir angewöhnen, Dich an
PEP-8 zu halten. Vor allem die Einrückung von 4 Leerzeichen.
Dann selltest Du `global` vermeiden, indem Du die Werte per `return` an den Aufrufer zurückgibst.
Re: Globale Namen definieren ???
Verfasst: Montag 26. Mai 2014, 19:16
von Zappelmann
Sirius3 hat geschrieben:als nächstes solltest Du Dir angewöhnen, Dich an
PEP-8 zu halten. Vor allem die Einrückung von 4 Leerzeichen.
Dann selltest Du `global` vermeiden, indem Du die Werte per `return` an den Aufrufer zurückgibst.
hmmmm erstmal danke für deine Anregung, aber bitte gibt es das auch in deutsch zu lesen, denn irgendwie ist ein so hochkonzentriertes Englisch nicht so ganz mein Ding....
Was die Einrückung von 4 Leerzeichen angeht, jo eigentlich versuche ich mich schon sehr daran zu halten. Aber ich hab den Bereich gefunden wo es nicht der Fall ist ich werde das dann korrigieren. Was die Codeänderung angeht. Ich werde drüber nachdenken und es mal austesten. Wenns funzt werde ich den Code daraufhin anpassen. Ja das mit dem return hab ich auch gelesen wegen Wertübergabe. Aber ich hab dabei halt auf nen Error mit global name define reagiert gehabt und deswegen das ganze ja hier überhaupt angefangen zu schreiben.
Aber ich werde mal weiter Versuche damit starten und schauen ob ich das richtig umgesetzt bekomme. Aber dieses PEP-8 Das muss ich erstmal verstehen was du mir damit sagen möchtest. Dann dahinter bin ich jetzt bisher noch nicht gekommen auser das es sich scheinbar um ein Style für Python Code geht. Aber vielleicht hast du da ja was ähnlihces was es auch auf deutsch gibt. Ansonsten werde ich später mal selber googlen.
MFG
Zappelmann
Re: Globale Namen definieren ???
Verfasst: Montag 26. Mai 2014, 20:59
von Zappelmann
Re: Globale Namen definieren ???
Verfasst: Dienstag 27. Mai 2014, 01:29
von Zappelmann
So das mit dem starten und stoppen des Scriptes über einen Taster hab ich schon gelöst. Ich hab dafür aber nen Schalter genommen und nen Taster zum testlauf. Jetzt konnte ich auch endlich mal das Script direkt in den Bootvorgang einbinden. Ohne das der direkt losfährt. Klappt wunderbar.
MFG
Zappelmann
Re: Globale Namen definieren ???
Verfasst: Dienstag 27. Mai 2014, 13:17
von EyDu
Zappelmann hat geschrieben:Das hättet ihr aber auch direkt schreiben können das es so einfach ist ^^.
Haben wir doch. Aber du verwendest noch immer gloabl-Anweisungen.
Zappelmann hat geschrieben:Aber ich werde mal weiter Versuche damit starten und schauen ob ich das richtig umgesetzt bekomme. Aber dieses PEP-8 Das muss ich erstmal verstehen was du mir damit sagen möchtest. Dann dahinter bin ich jetzt bisher noch nicht gekommen auser das es sich scheinbar um ein Style für Python Code geht. Aber vielleicht hast du da ja was ähnlihces was es auch auf deutsch gibt.
Ja, PEP 8 ist ein Style Guide an den du dich unbedingt halten solltest. Zumindest dann, wenn andere deinen Code lesen sollen. Was hier ja der Fall ist. Ansonsten solltest du einfach die Idee vergessen, dass es Dokumentation auf Deutsch gibt. Um Englisch wirst du nicht herumkommen.
Re: Globale Namen definieren ???
Verfasst: Mittwoch 25. Juni 2014, 13:14
von lackschuh
Hallo
Ich hab auch eine kleine Frage bzgl. globale Variablen. Was wäre die 'richtige' Alternative zu folgendem Beispiel:
Code: Alles auswählen
import time
count = 0
def counter():
while True:
count = count + 1
print count
time.sleep(1)
counter()
Code: Alles auswählen
UnboundLocalError: local variable 'count' referenced before assignment
so?
Code: Alles auswählen
import time
count = 0
def counter(count):
while True:
count = count + 1
print count
time.sleep(1)
counter(count)
Re: Globale Namen definieren ???
Verfasst: Mittwoch 25. Juni 2014, 13:19
von BlackJack
@lackschuh: Eher so:
Code: Alles auswählen
import time
def counter():
count = 0
while True:
count = count + 1
print count
time.sleep(1)
def main():
counter()
if __name__ == '__main__':
main()
Beziehungsweise:
Code: Alles auswählen
import time
from itertools import count
def counter():
for i in count(1):
print i
time.sleep(1)
Re: Globale Namen definieren ???
Verfasst: Mittwoch 25. Juni 2014, 13:21
von cofi
Das kommt drauf an, was du eigentlich willst. Die beiden Fragmente tun schliesslich nicht dasselbe: #1 benutzt und veraendert die globale Variable (wenn man `global` hinzufuegt) #2 benutzt nie eine globale Variable und der Parameter `count` ist nur der Startwert.
Wenn du beabsichtigst, dass sich das globale `count` veraendert, dann gibt es keine richtige Alternative. Das Problem ist schliesslich nicht die `global` Anweisung sondern die globale Variable.
Re: Globale Namen definieren ???
Verfasst: Mittwoch 25. Juni 2014, 13:25
von Hyperion
Als erstes würde man ``count`` als Konstante *groß* schreiben, also ``COUNT``.
Und ja, man sollte an Funktionen Parameter übergeben - dabei kann man dann aber auch gerne Default-Werte statt Konstanten setzen:
Die Frage ist dabei ja eher, ob man einen Wert *mehrfach* benötigt. Falls ja, kann man gerne eine Konstante nehmen, falls nein, imho besser einen Default-Parameter.
"Konstanten" sind hier natürlich reine Konvention aufgrund der Schreibweise!
Idiomatischer wäre es imho auch so:
Code: Alles auswählen
from itertools import count
from time import sleep
def counter(start=0):
for c in count(start):
print(c)
sleep(1)
Hier böte es sich eher / zudem an, die Wartezeit als Konstante zu hinterlegen oder auch als (Default)-Parameter zu übergeben.
Och menno, BJ war schneller

Re: Globale Namen definieren ???
Verfasst: Mittwoch 25. Juni 2014, 13:27
von lackschuh
Danke für die Infos. Vielleicht war das Beispiel nicht ganz das richtige. Angenommen ich definiere zu Beginn des Programms eine Variable mir dem Wert 0 (oder was auch immer). Diese Variable taucht aber nachfolgend in mehreren Funktionen und Klassen auf. Dann wäre nach BlackJack's Beispiel es so, dass man innerhalb einer jeden Funktion die Variable neu setzt.(?)
Ich beziehe mich auf
das hier.
mfg
Re: Globale Namen definieren ???
Verfasst: Mittwoch 25. Juni 2014, 13:36
von BlackJack
@lackschuh: Das ist immer noch alles sehr missverständlich formuliert. Was heisst zu Beginn des Programms? Im Quelltext auf Modulebene? Nein, da definiert man keine Variablen. Die Variable taucht auch nicht in mehreren Funktionen einfach so auf. Werte, ausser Konstanten, betreten Funktionen als Argumente. Welchen Wert der Name lokal dabei bekommt ist unabhängig davon an welchen Namen er bei einem Aufrufer gebunden ist.
Re: Globale Namen definieren ???
Verfasst: Mittwoch 25. Juni 2014, 13:41
von snafu
@lackschuh: Wenn die Variable nicht verändert wird oder wenn die Variable als gemeinsamer Startwert gilt, dann kann man sie situationsabhängig als Konstante definieren. Im Falle eines Startwertes sollte man den Startwert an einen neuen Namen binden und Veränderungen dann mit diesem neuen Namen durchführen. Zwar ist der neue Name zunächst nur eine Referenz auf das selbe Zahl-Objekt, welches auch von der Konstante referenziert wird, aber nach einer Rechenoperation wird ja ohnehin ein neues Zahl-Objekt als Resultat erzeugt und dieses wird dann halt neu an den zusätzlichen Namen gebunden (ich hoffe du kannst mir bis hier noch folgen). Somit kommt man gar nicht auf die Idee, irgendwas mit `global` hinzupfuschen. Wie gesagt: Das alles immer unter der Annahme, dass sich andere Funktionen ebenfalls nur für den Startwert und nicht für den veränderten Wert interessieren. Falls letzteres zutrifft, dann handelt es sich definitiv um keine Konstante, sondern um eine tatsächlich veränderliche Variable, dessen Definition man auf Modulebene vermeiden sollte.
Re: Globale Namen definieren ???
Verfasst: Montag 30. Juni 2014, 09:39
von lackschuh
Hallo
Danke für die Infos.
Also zB habe ich Startwerte oder Flags, welche zu Beginn im Quelltext den Wert '''0''' haben. Wie könnte man es anhand des unteren Beispiels erklären, wie global zu vermeiden wäre?. Die Erklärung von snafu verwirrt mich leicht bzw. ich kapier sie wohl nicht ganz :K
Code: Alles auswählen
status = 0
class EmailThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
global status
while True:
#mach was
if habe_mail == 1: # status wird auf 1 gesetzt
status = 1
def main():
global status
while True:
if status == 0:
pass # mach nichts
elif status = 1:
# Aufruf weiterer Funktionen
Vielen Dank
Re: Globale Namen definieren ???
Verfasst: Montag 30. Juni 2014, 10:32
von EyDu
Durch eine Queue-Objekt, welches du aus der main-Funktion dem E-Mail-Thread übergibst. Dann sparst du dir auch das Busy-Waiting und treibst deine Stromrechnung nicht in ungeahnte Höhen.
Re: Globale Namen definieren ???
Verfasst: Montag 30. Juni 2014, 10:43
von pillmuncher
EyDu hat geschrieben:...sparst du dir auch das Busy-Waiting und treibst deine Stromrechnung nicht in ungeahnte Höhen.
Aber man bekäme doch einen Teil davon wieder herein durch die ansonsten anfallenden Heizkosten, die man sich dadurch spart. Ich meine, angesichts des Wetters heute...
Re: Globale Namen definieren ???
Verfasst: Montag 30. Juni 2014, 14:18
von BlackJack
@lackschuh: Wie man das Beispiel am besten löst, hängt davon ab wie und was die beiden Threads eigentlich miteinander kommunizieren sollen. Ich sehe da denn Sinn von dem Flag nicht, beziehungsweise nicht wie man das mit vertretbarem Aufwand threadsicher hinbekommt ohne das der Thread der die Emails dann verarbeitet, den Test ob neue E-Mails vorhanden sind, nicht zumindest implizit noch man selber machen muss.
Re: Globale Namen definieren ???
Verfasst: Montag 30. Juni 2014, 15:12
von Sirius3
@lackschuh: je nach Anwendungsfall bekommst Du bei Deinem Ansatz Probleme, wenn mehr als eine Mail kommt. Wie läuft die Verarbeitung der Mails, wie wird der Inhalt von einem Thread zum anderen übertragen? Queues sind eine Möglichkeit, das sauber abzubilden.
Re: Globale Namen definieren ???
Verfasst: Montag 30. Juni 2014, 17:50
von jerch
@lackschuh:
Die Sinnhaftigkeit Deines Beispiels mal ausser Acht lassend hier das Beispiel ohne globale Variable und in threadsafe:
Code: Alles auswählen
# Weg damit, globals sind vorallem mit Threads Ausgeburten der Hölle!
# status = 0
class EmailThread(threading.Thread):
def __init__(self, status):
threading.Thread.__init__(self)
self.status = status
def run(self):
#global status
while True:
#mach was
if habe_mail == 1: # status wird auf 1 gesetzt
self.status.set()
def main():
#global status
# anstelle der globalen Variable nehmen wir eine threadsichere boolsche Variable.
status = threading.Event()
while True:
if not status.is_set():
pass # mach nichts
# vllt. dem Teil ein sleep gönnen ;)
#elif status = 1:
# nix elif hier, da eh nur 1|0 unterschieden wird
else:
...
# Aufruf weiterer Funktionen
...
# iwie fehlt noch der Aufruf des Mailthreads (am besten vor dem while, sonst wird das nie erreicht),
# da kommt das Flag mit rein:
emailthread = EmailThread(status)
# und hier rennt er los ...
emailthread.start()
Re: Globale Namen definieren ???
Verfasst: Montag 30. Juni 2014, 17:59
von BlackJack
@jerch: Ob das wirklich threadsafe (genug) ist kommt aber ganz darauf an was dieses Flag bedeutet und wer das wieder löscht.
Re: Globale Namen definieren ???
Verfasst: Montag 30. Juni 2014, 21:00
von jerch
BlackJack hat geschrieben:@jerch: Ob das wirklich threadsafe (genug) ist kommt aber ganz darauf an was dieses Flag bedeutet und wer das wieder löscht.
Inwiefern könnte das Flag hier nicht threadsafe sein?