Seite 1 von 1
Aus einer TRY in einer While "ausbrechen".
Verfasst: Samstag 24. Juli 2021, 21:16
von Holzkopp
Hey Leute,
ich habe eine While-Schleife, die wiederum eine Try-Funktion startet. Bei einer ganz bestimmten except soll die While-Schleife beendet werden.
Code: Alles auswählen
while True:
Aufruf Funktion
print("wait 10 sec...")
sleep(10)
Dann erledige eine andere Aufgabe
def Funktion:
try:
erledige eine Aufgabe
except1
print("Fehler1")
except2
print("ein anderer Fehler")
break
Ich kann wohl mit break nur die innerste Schleife beenden. Aber wie bekomme ich dann die While-Schleife auf False?
Die Möglichkeit dies mit except KeyboardInterrupt zu erledigen ist für mich keine Option, da so der Befehl "Dann starte eine andere Aufgabe" nicht ausgeführt wird.
Re: Aus einer TRY in einer While "ausbrechen".
Verfasst: Sonntag 25. Juli 2021, 08:12
von ThomasL
Innerhalb einer Funktion kann man diese per "return" verlassen und dabei sogar Werte zurück geben.

Re: Aus einer TRY in einer While "ausbrechen".
Verfasst: Sonntag 25. Juli 2021, 08:36
von Sirius3
@
forum@mong.de: zuerst einmal solltest Du gültige Pythonsyntax schreiben. Eingerückt wird auch nur mit 4 Leerzeichen pro Ebene, 8 sind etwas viel. Und Tabs benutzt man gar nicht, vor allem mischt man nicht.
Das `break` in `Funktion` funktioniert nicht, weil `Funktion` gar keine Schleife hat.
Wenn ich das Codefragment interpretieren müßte, hast Du eine Funktion, die so lange wiederholt werden soll, bis sie erfolgreich war. Und dieses "Erfolgreich" mußt Du natürlich der Aufrufenden Codestelle mitteilen, per Rückgabewert.
Code: Alles auswählen
def some_function():
try:
do_something()
except SomeException:
print("Fehler1")
except OtherException:
print("ein anderer Fehler")
return True
return False
while True:
success = some_function()
if success:
break
print("wait 10 sec...")
sleep(10)
Re: Aus einer TRY in einer While "ausbrechen".
Verfasst: Sonntag 25. Juli 2021, 12:10
von Holzkopp
Sirius3 hat geschrieben: Sonntag 25. Juli 2021, 08:36
Das `break` in `Funktion` funktioniert nicht, weil `Funktion` gar keine Schleife hat.
Wenn ich das Codefragment interpretieren müßte, hast Du eine Funktion, die so lange wiederholt werden soll, bis sie erfolgreich war. Und dieses "Erfolgreich" mußt Du natürlich der Aufrufenden Codestelle mitteilen, per Rückgabewert.
Das mit den 4 Leerzeichen ist mir bewusst. Wieso sind Tabulatoren eigentlich so schlecht?
Das Skript überprüft in der While-Schleife alle 10 Sekunden, ob auf meinem Raspberry Pi noch der Samba-Server läuft und signalisert mit LED das jeweilige Ergebnis.
Dafür habe ich eine Exception definiert, in deren Fall der Server neu gestartet wird.
Eine weitere Exception prüft, ob ein Zugriff auf den Inhalt des Servers funktioniert (Festplatte angeschlossen) und gibt eine Warnmeldung aus.
Noch eine weitere Exception prüft, ob überhaupt ein Samba-Server installiert wurde.
In diesem Fall kann das Skript komplett abgebrochen werden, weil eine weitere Prüfung (nach 10 Sekunden) nutzlos ist.
Ich hatte das Skript extra nur als Pseudo-Code gepostet, da es arg umfangreich ist.
Dein Skript mit meiner Logik angepasst müsste doch dann folgendermaßen lauten, oder?
Code: Alles auswählen
def some_function(Led-Variable):
try:
do_something()
except Server angehalten:
starte Server neu
except kein Server installiert:
print("Abbruch")
return True
return False
while True:
success = some_function(Led-Variable)
if success:
break
print("wait 10 sec...")
sleep(10)
So scheint es zu funktionieren!
Re: Aus einer TRY in einer While "ausbrechen".
Verfasst: Sonntag 25. Juli 2021, 12:52
von Sirius3
Dann fängst Du die Exception an der falschen Stelle ab. Das `except kein Server installiert` gehört auf oberster Ebene um die while-Schleife. Es macht ja keinen Sinn, eine Exception in einen Wahrheitswert umzuwandeln um den dann am einer anderen Stelle auszuwerten.
Re: Aus einer TRY in einer While "ausbrechen".
Verfasst: Montag 26. Juli 2021, 19:49
von Holzkopp
Das Skript soll ja endlos weiterlaufen, es sei denn, es wurde noch gar kein Samba-Server installiert (bzw. es wurde ein Fehler festgestellt, der nicht behoben werden kann). Nur dann soll ein Abbruch erfolgen und eine Nachricht per Telegram versendet werden.
Sirius3 hat geschrieben: Sonntag 25. Juli 2021, 12:52
Dann fängst Du die Exception an der falschen Stelle ab. Das `except kein Server installiert` gehört auf oberster Ebene um die while-Schleife. Es macht ja keinen Sinn, eine Exception in einen Wahrheitswert umzuwandeln um den dann am einer anderen Stelle auszuwerten.
Das verstehe ich nicht. Wo deiner Meinung nach müsste das Skript abgeändert werden?
Re: Aus einer TRY in einer While "ausbrechen".
Verfasst: Montag 26. Juli 2021, 20:08
von Sirius3
Fehler werden dort behandelt, wo es sinnvoll ist, und es ist nicht sinnvoll einen Fehler innerhalb der Schleife zu behandeln, wenn das nur dafür sorgt, dass die Schleife händisch abgebrochen wird.
Code: Alles auswählen
def main():
try:
while True:
try:
do_something(Led-Variable)
except Server angehalten:
starte Server neu
print("wait 10 sec...")
sleep(10)
except kein Server installiert:
print("Abbruch")
if __name__ == "__main__":
main()
Re: Aus einer TRY in einer While "ausbrechen".
Verfasst: Montag 26. Juli 2021, 21:12
von Holzkopp
Vielleicht reden wir an einander vorbei oder ich checks nicht.
Ich bin der Meinung, dass dein Vorschlag nicht funktionieren kann, weil except kein Server installiert in der "falschen Schleife" aufgeführt wird.
Also weg vom Pseudo-Code. Hier ist das Skript komplett, damit mein Plan deutlicher wird:
Code: Alles auswählen
#!/usr/bin/env python3
# coding=utf-8
from smb.SMBConnection import SMBConnection
from smb import smb_structs
import tempfile
from socket import gethostbyname
from time import sleep, strftime
from gpiozero import LED
from subprocess import run
USER = "pi"
PASSWORD = "123456789"
SERVER = "Raspi"
Freigabe = 'Toshiba'
Testdatei = '/samba.txt'
LED_PIN = 18
def connection_status(status_led):
try:
server_ip = gethostbyname(SERVER)
conn = SMBConnection(USER, PASSWORD, "name", SERVER, use_ntlm_v2 = True)
conn.connect(server_ip, 445)
file_obj = tempfile.NamedTemporaryFile()
conn.retrieveFile(Freigabe, Testdatei, file_obj)
file_obj.close()
conn.close()
print("Samba-Server läuft...")
status_led.on()
except ConnectionRefusedError:
print("Keine Verbindung zum Samba-Server.")
status_led.off()
run(['sudo', 'service', 'smbd', 'restart'])
run(['sudo', 'service', 'nmbd', 'restart'])
print("Samba-Server wird neu gestartet...")
except ConnectionResetError:
print("Es ist kein Samba-Server installiert.")
status_led.off()
return True
except smb_structs.OperationFailure:
print("Testdatei nicht gefunden")
status_led.blink()
return False
def main():
status_led = LED(LED_PIN)
while True:
success = connection_status(status_led)
if success:
print("Abbruch")
break
print("wait 10 sec...")
sleep(10)
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print(" Bye!")
Das Skript klappt wunderbar, bis auf die Tatsache, dass bei except ConnectionResetError das Skript munter weiter läuft (stets aufs neuen testet), ich es bei diesem Fehler aber gerne abbrechen würde.
Re: Aus einer TRY in einer While "ausbrechen".
Verfasst: Montag 26. Juli 2021, 21:22
von __blackjack__
@
forum@mong.de: Das sollte aber nicht passieren. Wobei anzumerken wäre, dass `success` entweder der komplett falsche Name ist, oder Du `True` und `False` austauschen und die Bedingung negieren solltest.
Beziehungsweise wie Sirius3 bereits vorgeschlagen hat die Ausnahme nicht auf der Ebene behandeln solltest wo sie jetzt in einen Wahrheitswert ”umgewandelt” wird. Ausnahmen wurde erfunden um solche Fehlerrückgabewerte loszuwerden, nun führst Du das da wieder ein.
Re: Aus einer TRY in einer While "ausbrechen".
Verfasst: Montag 26. Juli 2021, 21:30
von Sirius3
Mein Code passt doch exakt zu dem, was Dein Code machen sollte:
Code: Alles auswählen
#!/usr/bin/env python3
from smb.SMBConnection import SMBConnection
from smb import smb_structs
from socket import gethostbyname
from time import sleep, strftime
from gpiozero import LED
from subprocess import run
USER = "pi"
PASSWORD = "123456789"
SERVER = "Raspi"
FREIGABE = 'Toshiba'
TESTDATEI = '/samba.txt'
LED_PIN = 18
def connection_status(status_led):
try:
server_ip = gethostbyname(SERVER)
connection = SMBConnection(USER, PASSWORD, "name", SERVER, use_ntlm_v2=True)
connection.connect(server_ip, 445)
with open('/dev/null') as file:
connection.retrieveFile(FREIGABE, TESTDATEI, file)
connection.close()
print("Samba-Server läuft...")
status_led.on()
except ConnectionRefusedError:
print("Keine Verbindung zum Samba-Server.")
status_led.off()
run(['sudo', 'service', 'smbd', 'restart'])
run(['sudo', 'service', 'nmbd', 'restart'])
print("Samba-Server wird neu gestartet...")
except smb_structs.OperationFailure:
print("Testdatei nicht gefunden")
status_led.blink()
def main():
status_led = LED(LED_PIN)
try:
while True:
connection_status(status_led)
print("wait 10 sec...")
sleep(10)
except ConnectionResetError:
print("Es ist kein Samba-Server installiert.")
status_led.off()
except KeyboardInterrupt:
print(" Bye!")
if __name__ == "__main__":
main()
Re: Aus einer TRY in einer While "ausbrechen".
Verfasst: Dienstag 27. Juli 2021, 12:57
von Holzkopp
Ah, jetzt verstehe ich was du meinst!
Zudem scheine ich es mir mit meinem Code unnötig kompliziert gemacht zu haben.
Wenn ich deinen Code exakt übernehme, bekomme ich folgende Fehlermeldung:
Code: Alles auswählen
Traceback (most recent call last):
File "samba_check.py", line 52, in <module>
main()
File "samba_check.py", line 42, in main
connection_status(status_led)
File "samba_check.py", line 24, in connection_status
connection.retrieveFile(FREIGABE, TESTDATEI, file)
File "/home/pi/.local/lib/python3.7/site-packages/smb/SMBConnection.py", line 321, in retrieveFile
return self.retrieveFileFromOffset(service_name, path, file_obj, 0, -1, timeout)
File "/home/pi/.local/lib/python3.7/site-packages/smb/SMBConnection.py", line 353, in retrieveFileFromOffset
self._pollForNetBIOSPacket(timeout)
File "/home/pi/.local/lib/python3.7/site-packages/smb/SMBConnection.py", line 642, in _pollForNetBIOSPacket
self.feedData(data)
File "/home/pi/.local/lib/python3.7/site-packages/nmb/base.py", line 54, in feedData
self._processNMBSessionPacket(self.data_nmb)
File "/home/pi/.local/lib/python3.7/site-packages/nmb/base.py", line 75, in _processNMBSessionPacket
self.onNMBSessionMessage(packet.flags, packet.data)
File "/home/pi/.local/lib/python3.7/site-packages/smb/base.py", line 144, in onNMBSessionMessage
if self._updateState(self.smb_message):
File "/home/pi/.local/lib/python3.7/site-packages/smb/base.py", line 338, in _updateState_SMB2
req.callback(message, **req.kwargs)
File "/home/pi/.local/lib/python3.7/site-packages/smb/base.py", line 987, in readCB
file_obj.write(read_message.payload.data)
TypeError: write() argument must be str, not bytes
Re: Aus einer TRY in einer While "ausbrechen".
Verfasst: Dienstag 27. Juli 2021, 13:12
von Sirius3
Da muß man die Datei binär öffnen: `open('/dev/null', mode="wb")`
Re: Aus einer TRY in einer While "ausbrechen".
Verfasst: Dienstag 27. Juli 2021, 16:16
von __blackjack__
Statt "/dev/null" könnte man auch die Konstante `os.devnull` verwenden.
Re: Aus einer TRY in einer While "ausbrechen".
Verfasst: Dienstag 27. Juli 2021, 19:32
von Holzkopp
Jawoll, so klappts.
Ich habe zum einfacheren Testen einmal die
except smb_structs.OperationFailure
in die main-funktion verschoben:
Code: Alles auswählen
def main():
status_led = LED(LED_PIN)
try:
while True:
connection_status(status_led)
print("Wait 10 sec...")
sleep(10)
except smb_structs.OperationFailure:
print("Testdatei nicht gefunden")
status_led.blink()
except ConnectionResetError:
print("Es ist kein Samba-Server installiert.")
status_led.off()
except KeyboardInterrupt:
print(" Bye!")
Lösche ich TESTDATEI auf der Festplatte, wird die Fehlermeldung ausgeben, dass "Testdatei nicht gefunden" werden kann. Das Skripte sollte jetzt eigentlich abbrechen. Stattdessen läuft es aber immer noch weiter. Wenn ich nämlich jetzt eine gleichnamige Datei neu erstelle, wird mir nun bestätigt, das alles einwandfrei funktioniert.
Wäre das Skript tatsächlich abgebrochen worden, gäbe es keine weitere Prüfung und entsprechend auch nicht diese Rückmeldung. Ich bin verwirrt.
Re: Aus einer TRY in einer While "ausbrechen".
Verfasst: Dienstag 27. Juli 2021, 21:49
von Sirius3
Wie sieht denn nun das komplette Programm aus?
Re: Aus einer TRY in einer While "ausbrechen".
Verfasst: Donnerstag 29. Juli 2021, 16:52
von Holzkopp
Jetzt hab ich es doch endlich hinbekommen!
Ich sollte beim Schreiben besser aufpassen, dann funktionierts auch.
Vielen Dank für eure Hilfe!