Python Texteditor

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.
Benutzeravatar
Sr4l
User
Beiträge: 1091
Registriert: Donnerstag 28. Dezember 2006, 20:02
Wohnort: Kassel
Kontaktdaten:

Nur nicht unter Windows. Den der Befehl lautet nicht "os.startfile" sondern der Funktionsaufruf.

Windows kennt aber den Befehl "start". Was nun besser ist kann ich nicht beurteilen.

Du hast die Variable standardedit genannt, geöffnet wird aber bei allen Varianten nicht der Standard Editor sondern das verknüpfte Programm zum Dateitype, d.h für HTML, XML und andere geht je nach Einstellung ein Browser oder ein Editor auf, oder etwas ganz anderes ;-)
Nobuddy
User
Beiträge: 994
Registriert: Montag 30. Januar 2012, 16:38

Dann versuche ich es mal mit 'start' unter Windows, wenn ich ein Windows hätte ... :lol:

standardedit ist dann die falsche Bezeichnung für die Variable.
Besser wäre dann wohl was wie standardprog.
Nobuddy
User
Beiträge: 994
Registriert: Montag 30. Januar 2012, 16:38

Habe daraus eine Funktion gemacht:

Code: Alles auswählen

def sysprog(filename):
    while True:
        # 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 = 'os.startfile'
            standardedit = 'start'
        else:
            print('Betriebssystem konnte nicht ermittelt werden.')
            break
        print('Datei %s wird mit dem Standardprogramm\nIhres Betriebsystem zum Editieren geöffnet!' % filename)
        process = subprocess.Popen([standardedit, filename])
        process.wait()
        break
Habe da noch eine Frage, wie kann ich eine wie oben geöffnete Datei mit dem Programm im Code wieder schließen?
Zuletzt geändert von Nobuddy am Freitag 17. August 2012, 10:13, insgesamt 4-mal geändert.
deets

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?
Nobuddy
User
Beiträge: 994
Registriert: Montag 30. Januar 2012, 16:38

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.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

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.
Das Leben ist wie ein Tennisball.
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?
Nobuddy
User
Beiträge: 994
Registriert: Montag 30. Januar 2012, 16:38

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?
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.
Nobuddy
User
Beiträge: 994
Registriert: Montag 30. Januar 2012, 16:38

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)))
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

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.
Das Leben ist wie ein Tennisball.
Nobuddy
User
Beiträge: 994
Registriert: Montag 30. Januar 2012, 16:38

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?
Benutzeravatar
Sr4l
User
Beiträge: 1091
Registriert: Donnerstag 28. Dezember 2006, 20:02
Wohnort: Kassel
Kontaktdaten:

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()
Nobuddy
User
Beiträge: 994
Registriert: Montag 30. Januar 2012, 16:38

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:
Malachite
User
Beiträge: 34
Registriert: Sonntag 24. Juni 2012, 13:43
Wohnort: Berlin

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'
Nobuddy
User
Beiträge: 994
Registriert: Montag 30. Januar 2012, 16:38

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?
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

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.
Das Leben ist wie ein Tennisball.
Nobuddy
User
Beiträge: 994
Registriert: Montag 30. Januar 2012, 16:38

@EyDu, ich arbeite das Tutorial zu Exceptions durch, Danke für den Hinweis. :wink:
Nobuddy
User
Beiträge: 994
Registriert: Montag 30. Januar 2012, 16:38

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
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

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")
Das Leben ist wie ein Tennisball.
Antworten