Try-Except-Import eleganter gestalten

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

Hi,

ich importiere in meinem Code ElementTree. Dabei soll die lxml-Variante bevorzugt werden und dann quasi nach unten hin auf mögliche Alternativen zurückgegriffen werden:

Code: Alles auswählen

try:
    # The preferred implementation
    from lxml import etree as ET
except ImportError:
    try:
        # In standard library since Python 2.5
        from xml.etree import cElementTree as ET
    except ImportError:
        try:
            # C implementation installed from source
            import cElementTree as ET
        except ImportError:
            # Python implementation installed from source
            from elementtree import ElementTree as ET
Ich persönlich finde diese Verschachtelung etwas unglücklich. Würde man das in "gutem" Code so belassen (ist es also gar nicht unglücklich) oder gibt es bessere Wege? Oder würdet ihr sagen, der Nutzer möchte lieber selbst entscheiden, welche Implementierung verwendet wird?

Mein Ziel ist eigentlich nur, dass ich eine etwas abgeänderte API für Zugriff und Erstellung von Elementen verwenden möchte. Eine Funktion set_title() würde meinetwegen das <html>-, das <head>- und das <title>-Element erstellen (sofern nicht vorhanden) und den übergebenen Text da reinpacken. Aber das nur am Rande.
lunar

Ich denke nicht, dass man das wesentlich eleganter gestalten kann. Mein einziger Kritikpunkt wäre, dass man ElementTree meinem Empfinden nach eigentlich eher als "etree" denn als "ET" kennt, und daher eigentlich auch als "etree" importiert. Zudem sind durchgehend groß geschriebene Bezeichner gemäß PEP 8 ja eigentlich Konstanten vorbehalten.

Ich persönlich halte diese Chose aber für unnötig. "lxml" braucht man nur, wenn man seine erweiterte API nutzt. Ansonsten ist es bestenfalls schneller. Wenn man diese Geschwindigkeit braucht, dann hängt das Programm auch hart von lxml ab, und die Rückgriffe auf andere Varianten sind falsch. Hängt das Programm nicht von dieser Geschwindigkeit ab, dann fällt das meines Erachtens unter Premature Optimization. So viel schneller kann lxml gar nicht sein, als das das auf heutigen Systemen im Durchschnitt eine Rolle spielt.

Der Rückgriff auf die Upstream-Variante von ElementTree ist meines Erachtens auch unnötig. Die kommt ja nur dann zum Tragen, wenn man überhaupt noch Python 2.4 unterstützen möchte. In diesem Fall würde ich aber einfach gleich das Upstream-Modul voraussetzen, dann kann man nämlich auch neuere, effizientere Varianten dieses Moduls verwenden. Die Python-Variante kann man ja auch direkt im eigenen Programm einbetten, wenn man auf dem Zielsystem keine Erweiterungsmodule installieren kann. Ein Modul mehr oder weniger bringt angesichts heutiger Speichergrößen niemanden mehr um den Verstand.

Meines Erachtens ist das Ganze eine völlig unnötige Optimierung, die keinen relevanten Vorteile für das Programm mit sich bringt, sondern nur eine zusätzliche Fehlerquelle darstellt oder zusätzlichen Testaufwand mit sich bringt. Denn als guter Entwickler wärst Du nun eigentlich verpflichtet, dein Programm auch mit jedem dieser Module zu testen, schon allein, um auszuschließen, dass du versehentlich auf spezielle "lxml"-Funktionalität zugreifst, die bei den anderen Varianten nicht vorhanden ist, oder dass du über subtile Verhaltensunterschiede (z.B. im Bezug auf "Element.getchildren()") stolperst.
Benutzeravatar
snafu
User
Beiträge: 6744
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Gut, dann werde ich wohl auf xml.etree.cElementTree zurückgreifen. Die erweiterte lxml-Funktionalität hinsichtlich XPath und dergleichen brauche ich an dieser Stelle nicht. IMO rechtfertigt das daher keine harte Abhängigkeit, auch wenn es kein Beinbruch wäre, sich das Ding notfalls zu installieren. Danke für's Feedback. :)
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

snafu hat geschrieben:IMO rechtfertigt das daher keine harte Abhängigkeit, auch wenn es kein Beinbruch wäre, sich das Ding notfalls zu installieren.
Das gilt nicht unbedingt fuer MacOS X .. da ist das durchaus nicht ganz so einfach (ich glaub sma hatte da auch schon mal was ausfuehrlicheres geschrieben).
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

Wenn du sowas machst, solltest du auch auf die Exceptions Acht geben, xml.etree.ElementTree wirft zum Beispiel xml.parsers.expat.ExpatError.
Antworten