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.
Nobuddy
User
Beiträge: 996
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: 996
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: 996
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.
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

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.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

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...
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Nobuddy
User
Beiträge: 996
Registriert: Montag 30. Januar 2012, 16:38

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:
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

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

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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

Der Fehler scheint auf Seite zwei entstanden zu sein, von dort aus wurde dann wahrscheinlich munter kopiert und nicht genauer gelesen. Zumindest bin ich so vorgegangen.
Das Leben ist wie ein Tennisball.
Nobuddy
User
Beiträge: 996
Registriert: Montag 30. Januar 2012, 16:38

Hallo jens,
werde mich mit Deinem Code beschäftigen und testen.
Danke für einen weiteren Input! :wink:

@Leonidas, @EyDu, was soll das mit dem 'herausfinden' ala 'herraus finden'!?
lunar

@Nobuddy Das bezieht sich auf den offensichtlichen Rechtschreibfehler in der Nachricht der Ausnahme, die in den verschiedenen Beispielen hier ausgelöst wird.
Nobuddy
User
Beiträge: 996
Registriert: Montag 30. Januar 2012, 16:38

@lunar, Danke ... habś jetzt auch gesehen ... :lol:
Nobuddy
User
Beiträge: 996
Registriert: Montag 30. Januar 2012, 16:38

@jens, habe Deinen Vorschlag mir angeschaut, welch eine weitere Variante darstellt.
Funktionieren, tut es wie die Anderen auch, wobei mir persönlich der Vorschlag von snafu eher zusagt, da es kürzer, übersichtlicher und für mich verständlicher ist.

Danke und Grüße
Nobuddy
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Das sehe ich anders ;)

Zum einen, sollte man sys.platform.startswith(...) benutzen. Außerdem sind die Keys bei snafu Variante nicht brauchbar, siehe auch: http://docs.python.org/library/sys.html#sys.platform

Zum anderen finde ich bei mir besser, das die "Konfigurations"-Daten oben im skript stehen würden. Das macht gerade bei solchen Dingen Sinn. (Ich packe sowas immer direkt unter den imports)

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ich verwende platform.system() und da sind die Schlüsselnamen durchaus brauchbar. Ich frage mich auch, wie du darauf kommst, dass man nur `sys.platform` verwenden soll.

Und das Dictionary kann man *natürlich* auch außerhalb der Funktion haben. Finde die Argumentation ehrlich gesagt etwas zu dürftig, als dass sie mich überzeugen würde. Ich halte meine Variante jedenfalls für lesbarer und verständlicher, wie Nobuddy schon sagte. Sofern dir kein *echter* Nachteil einfällt, sehe ich auch nicht, wieso man sie deshalb nicht benutzen sollte. Ich will sie ja keinem aufzwingen, frage mich aber, wieso davon abgeraten wird.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

snafu hat geschrieben:Ich verwende platform.system()
Das habe ich doch glatt übersehen ;)

Hab mir mal den Code zu dem angeschaut: http://hg.python.org/cpython/file/2.7/Lib/platform.py
Ist also letztlich das was os.uname() als erstes zurück liefert.

Über die Unterschiede zwischen sys.platform, os.name und platform.system() gibt es z.B. hier info's:
http://stackoverflow.com/questions/4553 ... orm-system

Vielleicht ist es sogar ratsam os.name zu nutzten? -> http://docs.python.org/library/os.html#os.name Denn dabei hat man "feste" mögliche Werte.

Oder noch anders gelöst: Nicht den OS Namen nehmen, sondern zu prüfen, ob "start", "xdg-open" oder "open" verfügbar ist?

EDIT: Interessant ist auch: http://stackoverflow.com/questions/1854 ... running-on
Würde mich mal interessieren, ob es eine vollständige Tabelle mit sys.platform, os.name und platform.system() für alle möglichen Platformen gibt...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

jens hat geschrieben:Oder noch anders gelöst: Nicht den OS Namen nehmen, sondern zu prüfen, ob "start", "xdg-open" oder "open" verfügbar ist?
Ginge natürlich auch. Wobei ich da ein bißchen Bauchschmerzen hinsichtlich potenzieller Namenskollisionen hätte. Also dass es zufällig ein Linux-Tool gibt, das `start` heißt, aber etwas ganz anderes tut, oder sowas. Da müsste man dann schon auf Verhalten testen, oder z.B. gucken, was von `--help` zurückgegeben wird. Klingt mir - wenn man es ordentlich machen will - etwas zu kompliziert für diese Aufgabe.

`os.name` dürfte auch relativ robust sein. Nähere Details will man ja meist gar nicht wissen und man hätte auch dort keine hässliche `.startswith()`-Verzweigung, sondern könnte beim Dict bleiben. Allerdings ist es halt nicht ganz so lesbar wie `platform.system()` und daher für mich persönlich nur an zweiter Stelle. Etwas irritierend ist, dass es zu `platform.system()` anscheinend keine ordenliche Doku gibt, wo alle möglichen Werte drinstehen.

/edit: Es gibt unter Linux tatsächlich das Kommando `start`.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

snafu hat geschrieben:anscheinend keine ordenliche Doku gibt, wo alle möglichen Werte drinstehen.
Dann last uns doch mal selber sammeln!

Ich hab eine Wiki Seite gestartet:
http://wiki.python.de/platform%20unterscheiden

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Antworten