Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
deets hat geschrieben:Und das while True ist warum da?
Vielleicht möchte er nur die Götter beschwören, dass sie doch endlich wieder Ladung aus großen Vögeln abwerfen
Nobuddy hat geschrieben:Vielleicht habe ich da mal was falsch verstanden. Dachte es wäre immer gut, eine bestimmte Situation mit break zu beenden. Ist das falsch?
Und warum glaubst du, dass das gut sein soll? Hier ist die Schleife doch offensichtlich total unnötig.
deets hat geschrieben:Und das while True ist warum da? Wo du doch eh dauernd raus-breakst? Und warum printed eine solche Funktion eine Fehlermeldung anstatt eine Exception zu schmeissen, mit der du im umgebenden Code etwas anfangen kannst, statt einfach so zu tun, als ob alles ok gewesen waere?
Vielleicht habe ich da mal was falsch verstanden. Dachte es wäre immer gut, eine bestimmte Situation mit break zu beenden. Ist das falsch?
Das mit der Exception, ist eine gute Idee, werde das ändern.
Man benutzt break, wenn man es braucht, um aus einer Schleife auszubrechen. Und eine Schleife braucht man, wenn man Code mehr als einmal laufen lassen will. Brauchst du in deinem gezeigten Code eine Schleife? Nein. Also brauchst du auch kein break. Du kannst natuerlich auch so progammieren:
Da habe ich wohl wieder einen Treffer gelandet ...
Sorry, Ihr habt Recht, ändere es entsprechend.
Das mit der Exception, ist mir allerdings im nach hinein nicht klar.
Im ersten Teil überprüfe ich ja nur, welches der mir bekannten Betriebsystemen hier läuft.
Anschließend weise ich den Betriebsystemen, eine Variable mit dem spezifischen Befehl zum Starten des Standardprogrmmes zu.
Ich bekomme keine Exception so zu Stande.
Wie kann ich das mit der Exception bewerkstelligen?
Bitte arbeite ein Tutorial zum Thema Exceptions durch und stell dann konkrete Fragen. Dir jetzt hier saemtliche Konstrukte von Python vorzukauen ist ein bisschen viel.
def sysprog(filename):
# Betriebssytem ermitteln und Datei mit Standardprogramm öffnen.
linux = sys.platform.startswith('lin')
osx = sys.platform.startswith('os')
windows = sys.platform.startswith('win')
text = ('Datei %s wird mit dem Standardprogramm\nIhres Betriebsystem zum Editieren geöffnet!' % filename)
if linux:
standardedit = 'xdg-open'
print(text)
elif osx:
standardedit = 'open'
print(text)
elif windows:
# standardedit = 'os.startfile'
standardedit = 'start'
print(text)
try:
process = subprocess.Popen([standardedit, filename])
process.wait()
except UnboundLocalError:
print('Sie arbeiten mit dem Betriebssystem %s.' % sys.platform)
print('Das Standardprogramm zum Starten von %s, ist nicht bekannt.\n' % filename)
print('Öffnen Sie die Datei %s zum Editieren mit einem Texteditor.' % filename)
print('Die Datei %s befindet sich unter\n%s.' % (filename, os.path.realpath(filename)))
Du hast wirlich ein Händchen dafür, die schlechtesten aller verfügbaren Ansätze umzusetzen ^^ Generell kann man sagen, dass das Abfangen eines UnboundLocalError keine gute Idee ist, da dies der perfekte Ort ist, um sich richtig schöne Fehler in das Programm zu bauen. Stell dir mal vor, du hättest "filename" in dem try-Block verkehrt geschrieben oder, was noch viel schlimmer ist, du rufst im try-Block eine Funkion auf, welche einen UnboundLocalError wirft. Damit hast du dir dann im Prinzip das Debughorrszenario geschaffen.
Weiter kommt hinzu, dass du in jedem if/elif-Block den Text ausgist. Wir haben dich schon mehrfach darauf hingewiesen, dass man Code nicht kopiert. Das kann man doch problemlos zusammenfassen. Natürlich vermischt du auch wieder Ausgabe und Logik.
Nun zu deinem eigentlichen Problem: deets hat dich doch darauf hingewiesen, dass Ausgaben von Fehlermeldungen keine ausreichende Fehlerbehandlung sind. Wenn du so mit Fehlern umgehst, wird eine Meldung ausgegeben und dann Programm einfach irgendwo mit einer Ausnahme crashen oder im schlimmsten Fall einfach undefiniert weiterlaufen. Das kann natürlich nur zu interessantem Verhalten und unmöglich zu debuggendem Code führen. Du sollst hier keine Exception abfangen, sondern deine eigene Exception werfen, wenn du kein Programm zum öffnen finden konntest. Dein Programm kann dann an geeigneter stelle diese Ausnahme behandeln und deterministisch darauf reagieren. Bei dir kann man nur hoffen und beten, dass in einem Fehlerfall nichts kaputt geht.
Ich war mir eigentlich sicher, hier den richtigen Ansatz zu haben.
Schreibfehler sind immer ein Risiko, welches man aber beim Schreiben und Testen vom Code feststellen kann.
Ausgaben von Fehlermeldungen keine ausreichende Fehlerbehandlung, das ist richtig aber für jemand der dann das Programm nutzt, zumindest eine verständliche Info.
Vielleicht könntet Ihr mir in kurzen Zügen zeigen, wie es richtig wäre?
Noch was zu xdg-open: Es ist nicht nur auf Linux, sondern auf den meisten unixoiden Systemen installiert (bei Solaris und manchen Linux-Distributionen muss man xdg-utils nachinstallieren), daher würde ich es folgendermaßen schreiben, denn wenn ein Programm nicht unter Windows läuft, ist davon auszugehen, dass es auf einem unixoiden System läuft:
if os.platform.startswith('win'):
startcmd = 'start' # standardedit trifft hier ja nicht mehr zu…
elif os.platform.startswith('darwin'): # und nicht 'os' ;)
startcmd = 'open'
else:
startcmd = 'xdg-open'
Hallo Malachite,
Dein Code verkürzt das Ganze nochmal auf das Wesentliche.
Daß xdg-open auf den meisten unixoiden Systemen installiert ist, kann schon sein.
Aber auf eine Exception kann jedoch nicht verzichtet werden.
Der Code mit der Exception sollte so richtig sein, bin mir aber nicht ganz sicher.
Wie soll das denn funktionieren? Es gibt doch überhaupt keine Möglichkeit, dass das raise jemals erreicht wird. Hast du mal ein Tutorial zu Exceptions durchgearbeitet? Und warum testest du deinen Code nicht, dann wäre dir sofort aufgefallen, dass der Code nicht funktioniert.
Du wirst es vielleicht nicht glauben, aber so sollte deine Lösung aussehen. Im Idealfall erstellst du noch deine eigene Exception, dann kannst du etwas granularer mit den Fehlern umgehen. RuntimeException ist noch etwas sehr allgemein.
Ist natürlich etwas fortgeschrittener und mag teils Geschmackssache sein. In Python tendiert man aber generell eher zu Wörterbüchern als zu einem Haufen von `if`/`elif`-Konstrukten. Wobei sich die Anhäufung hier natürlich noch in Grenzen hält.
Früher oder später würde ich anstatt `RuntimeError` wohl eine eigene Exception bevorzugen (sprach EyDu ja schon an). Der neue Exception-Typ kann aber IMHO durchaus von `RuntimeError` abgeleitet werden.
snafu hat geschrieben: In Python tendiert man aber generell eher zu Wörterbüchern als zu einem Haufen von `if`/`elif`-Konstrukten. Wobei sich die Anhäufung hier natürlich noch in Grenzen hält.
+1
Ich war schon drauf und dran auf mein Textmenü-Tutorial (erneut) hinzuweisen, alleine aus der Erkenntnis, dass Nobuddy immer noch nicht den Blick für *zusammenhängende* oder *voneinander abhängige* Daten hat. Klar, muss man das bei drei Elemente nicht zwangsweise - zumal da eher kaum etwas hinzukommen wird - aber als Fingerübung schadet so etwas nie
linux = sys.platform.startswith('lin')
osx = sys.platform.startswith('os')
windows = sys.platform.startswith('win')
if linux:
standardedit = 'xdg-open'
elif osx:
standardedit = 'open'
elif windows:
standardedit = 'start'
Wenn man dreimal dieselbe Funktion mit verschiedenen Parametern aufruft und abhängig vom Ergebnis dann ein anderes Datum bestimmt, dann sollten eben die Alarmglocken schrillen, dass man Copy&Paste-Programmierung betreibt...
Hallo EyDu und snafu,
beide Beispiele von Euch sind wirklich klasse und für mich auch verständlich.
Der Code von EyDu, ist so wie ich ihn bisher kenne.
snafuś Code hat aber was für sich und imponiert mir sehr.
snafu hat geschrieben:Früher oder später würde ich anstatt `RuntimeError` wohl eine eigene Exception bevorzugen (sprach EyDu ja schon an). Der neue Exception-Typ kann aber IMHO durchaus von `RuntimeError` abgeleitet werden.
Das wäre dann wohl 'UnsupportedOSError'. Da muß ich mich aber noch mehr damit auseinandersetzen.
@Hyperion, es ist nicht einfach Altlasten abzuschütteln ... und ich weiß selbst, daß in meinem Code noch etliches zu ändern ist.
Aber, wie sagt man so schön "Erkenntnis ist der erste Schritt" ...
import sys
CMD_INFO = {
'win': 'start',
'linux': 'xdg-open',
'darwin': 'open' # Mac OS X
}
def get_cmd():
for indetifier, cmd in CMD_INFO.items():
if sys.platform.startswith(indetifier):
return cmd
raise UnsupportedOSError("Konnte Betriebsystem nicht herraus finden")
Darf ich euch mal fragen was "herraus finden" ist? Ich kenne nur das Wort "herausfinden", aber wenn man in Bayern lebt hat man kein Gespür für die deutsche Sprache.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice