Seite 2 von 3

Re: Python Texteditor

Verfasst: Freitag 17. August 2012, 10:22
von EyDu
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 :D
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.

Re: Python Texteditor

Verfasst: Freitag 17. August 2012, 10:35
von deets
Nobuddy hat geschrieben:
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:

Code: Alles auswählen

while True:
    while True:
         while True:
              print "einmal ausgefuehrt"
              break
         break
     break
Aber warum sollte man sowas machen?

Re: Python Texteditor

Verfasst: Freitag 17. August 2012, 10:39
von Nobuddy
Da habe ich wohl wieder einen Treffer gelandet ... :lol:
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?

Re: Python Texteditor

Verfasst: Freitag 17. August 2012, 11:32
von deets
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.

Re: Python Texteditor

Verfasst: Freitag 17. August 2012, 12:09
von Nobuddy
Vergiss das Thema Exception, habe es gelöst.

Code: Alles auswählen

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)))

Re: Python Texteditor

Verfasst: Freitag 17. August 2012, 12:20
von EyDu
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.

Re: Python Texteditor

Verfasst: Freitag 17. August 2012, 13:24
von Nobuddy
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?

Re: Python Texteditor

Verfasst: Freitag 17. August 2012, 14:16
von Sr4l
Ganz grob, auch das könnte man besser trennen, aber ich wollte mich an deinem Code halten (ungetestet, und im Browser eingerückt ;-) ).

Code: Alles auswählen

def sysprog():
     # Betriebssytem ermitteln und Datei mit Standardprogramm öffnen.
     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'
     else:
         raise RuntimeError("Konnte Betriebsystem nicht herraus finden")
     return standardedit

def fileopen(filename):
    try:
         default_program = sysprog()
    except RuntimeError, e:
        print(e)
    else:
        print('Datei %s wird mit dem Standardprogramm\nIhres Betriebsystem zum Editieren geöffnet!' % filename)
        process = subprocess.Popen([default_program, filename])
        process.wait()

Re: Python Texteditor

Verfasst: Freitag 17. August 2012, 15:57
von Nobuddy
Hallo Sr4l,
Danke für Deinen Input, der Code sieht gut aus, wäre aber da drauf nicht gekommen.
Aber jetzt habe ich wieder etwas dazu gelernt. :wink:

Einziger Schönheitsfehler ist hier

Code: Alles auswählen

except RuntimeError, e:
dies funktioniert bei mir nur mit

Code: Alles auswählen

except RuntimeError as e:
An sonst funktioniert der Code von Dir prima, Danke!

Da hab ich noch eine Menge zu lernen und hoffe auch auf Eure zukünftige Unterstützung. :wink:

Re: Python Texteditor

Verfasst: Freitag 17. August 2012, 20:31
von Malachite
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:

Code: Alles auswählen

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'

Re: Python Texteditor

Verfasst: Samstag 18. August 2012, 09:51
von Nobuddy
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.

Code: Alles auswählen

def sysprog():
     # Betriebssytem ermitteln und Datei mit Standardprogramm öffnen.
    if sys.platform.startswith('win'):
        startcmd = 'start'
    elif sys.platform.startswith('darwin'):
        startcmd = 'open'
    else:
        try:
            startcmd = 'xdg-open'
        except:
            raise RuntimeError("Konnte Betriebsystem nicht herraus finden")
    return startcmd
Wäre das so ok?

Re: Python Texteditor

Verfasst: Samstag 18. August 2012, 10:11
von EyDu
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.

Re: Python Texteditor

Verfasst: Samstag 18. August 2012, 10:17
von Nobuddy
@EyDu, ich arbeite das Tutorial zu Exceptions durch, Danke für den Hinweis. :wink:

Re: Python Texteditor

Verfasst: Samstag 18. August 2012, 11:39
von Nobuddy
Wie ich es mit obiger Konstellation und der Exception gehen soll, konnte ich noch keine Lösung finden.

Ich habe den Code jetzt so abgeändert, daß es keine probleme gibt.

Code: Alles auswählen

def sysprog():
     # Betriebssytem ermitteln und Datei mit Standardprogramm öffnen.
    if sys.platform.startswith('lin'):
        startcmd = 'xdg-open'
    elif sys.platform.startswith('darwin'):
        startcmd = 'open'
    elif sys.platform.startswith('win'):
        startcmd = 'start'
    else:
        raise RuntimeError("Konnte Betriebsystem nicht herraus finden")
    return startcmd

Re: Python Texteditor

Verfasst: Samstag 18. August 2012, 11:55
von EyDu
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.

Code: Alles auswählen

class UnsupportedOSError(Exception): pass

def sysprog():
    ...
    else:
        raise UnsupportedOSError("Konnte ...")
Edit: etwas kürzer wird es, wenn du gleich in den if/elif-Zweigen ein return machst, dann kannst du dir am Ende das else sparen:

Code: Alles auswählen

def sysprog():
    """
    BENUTZE DOC-STRINGS ZUR BESCHREIBUNG VON FUNKTIONEN
    Betriebssytem ermitteln und Datei mit Standardprogramm öffnen.
    """

    if sys.platform.startswith('lin'):
        return 'xdg-open'
    elif sys.platform.startswith('darwin'):
        return 'open'
    elif sys.platform.startswith('win'):
        return 'start'

    raise UnsupportedOSError("Konnte Betriebsystem nicht herraus finden")

Re: Python Texteditor

Verfasst: Samstag 18. August 2012, 12:06
von snafu
Alternativvorschlag mit Wörterbuch und Nutzung von `platform.system()`:

Code: Alles auswählen

def get_starter():
    try:
        return {'Windows': 'start',
                'Linux': 'xdg-open',
                'Darwin': 'open'
               }[platform.system()]
    except KeyError:
        raise RuntimeError(
                'Passender Starter konnte nicht ermittelt werden')
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.

Re: Python Texteditor

Verfasst: Samstag 18. August 2012, 12:40
von Hyperion
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 :-)

Denn Code wie dieser ist eben umständlich.

Code: Alles auswählen

    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...

Re: Python Texteditor

Verfasst: Samstag 18. August 2012, 12:45
von Nobuddy
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" ... :wink:

Re: Python Texteditor

Verfasst: Montag 20. August 2012, 09:38
von jens
ich würde es vielleicht so machen:

Code: Alles auswählen

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")

Re: Python Texteditor

Verfasst: Dienstag 21. August 2012, 15:50
von Leonidas
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.