Bedingter Import von Modulen in Python

140

In meinem Programm möchte ich simplejson oder json importieren, je nachdem, ob das Betriebssystem des Benutzers Windows oder Linux ist. Ich nehme den Betriebssystemnamen als Eingabe vom Benutzer. Ist es nun richtig, Folgendes zu tun?

osys = raw_input("Press w for windows,l for linux")
if (osys == "w"):
    import json as simplejson
else:
    import simplejson  
Tim
quelle
33
Warum nehmen Sie den Betriebssystemnamen als Eingabe vom Benutzer? Schauen Sie in das Plattformmodul. docs.python.org/library/platform.html platform.platform() oder platform.system()sollte das tun, was Sie brauchen, anstatt dass ein Benutzer jedes Mal etwas eingeben muss, wenn der Code ausgeführt wird.
Joe Kington
56
@ S.Lott: Ernst? Sie wissen, dass Up / Downvotes die Qualität der Frage widerspiegeln sollen , oder? Und nicht, ob Sie mit etwas anderem im OP-Code einverstanden sind .
Jalf
2
@jalf: Es ist in jeder Hinsicht eine schlechte Frage außer Grammatik. Es sollte nicht als Top-Antwort auf irgendeine Art von Suche gefunden werden.
S.Lott
11
@ S.Lott Es ist nichts Falsches daran zu wissen, ob bedingte Importe pythonisch sind. Und offensichtlich stimmen andere zu, da es trotz Ihrer Bemühungen +50 Stimmen hat.
SARose
5
+1 für das gesuchte Konzept (Import nur bei Verwendung von Win); und ein weiteres konzeptionelles +1, um die lächerliche Abwertung zu kompensieren.
S3DEV

Antworten:

182

Ich habe gesehen, dass diese Redewendung häufig verwendet wird, sodass Sie nicht einmal am Betriebssystem schnüffeln müssen:

try:
    import json
except ImportError:
    import simplejson as json
Matt Williamson
quelle
17
Sie sollten zuerst versuchen, zu importieren, simplejson as jsonda es sich wahrscheinlich um eine neuere (schnellere) Version des Standardmoduls handelt json.
Seppo Erviälä
oder ujsonfür Geschwindigkeit
lababidi
59

Um die Frage in Ihrem Titel zu beantworten, aber nicht den speziellen Fall, den Sie angeben, ist es vollkommen richtig, Tonnen von Paketen tun dies. Es ist wahrscheinlich besser, das Betriebssystem selbst herauszufinden, als sich auf den Benutzer zu verlassen. Hier ist pySerial als Beispiel.

serial/__init__.py

import sys

if sys.platform == 'cli':
    from serial.serialcli import Serial
else:
    import os
    # chose an implementation, depending on os
    if os.name == 'nt':  # sys.platform == 'win32':
        from serial.serialwin32 import Serial
    elif os.name == 'posix':
        from serial.serialposix import Serial, PosixPollSerial, VTIMESerial  # noqa
    elif os.name == 'java':
        from serial.serialjava import Serial
    else:
        raise ImportError(
            "Sorry: no implementation for your platform ('{}') available".format(
                os.name
            )
        )

Dies sollte nur in Fällen verwendet werden, in denen Sie davon ausgehen und eine starke Garantie dafür benötigen, dass bestimmte Schnittstellen / Funktionen vorhanden sind: z. B. eine aufgerufene 'Datei' /dev/ttyX. In Ihrem Fall: Wenn Sie sich mit JSON befassen, gibt es nichts, was tatsächlich betriebssystemspezifisch ist, und Sie überprüfen nur, ob das Paket vorhanden ist oder nicht. In diesem Fall nur try, um es zu importieren und mit einem exceptFallback zurückzugreifen, wenn es fehlschlägt:

try:
    import some_specific_json_module as json
except ImportError:
    import json
Nick T.
quelle
11
Nein, es ist sehr falsch, Betriebssystemnamen fest zu codieren, um zu entscheiden, ob sie verfügbar sind simplejsonoder jsonnicht. Sie zitieren Code aus inhärent betriebssystemspezifischen Importen, was ein ganz anderer Fall ist. Siehe Matts Antwort für den richtigen Ansatz.
Glenn Maynard
16
@Glenn Maynard: Ich würde dich dann aufschieben; Ich habe das jsonPaket noch nie verwendet und versucht, die allgemeinere Frage "Können Sie bedingte Importe von Modulen durchführen?" Zu beantworten.
Nick T
7

Es ist nicht ratsam, json oder simplejson an die Betriebssystemplattform zu binden. simplejson ist eine neuere und erweiterte Version von json, daher sollten wir zuerst versuchen, sie zu importieren.

Basierend auf der Python-Version können Sie unten versuchen, json oder simplejson zu importieren

import sys
if sys.version_info > (2, 7):
    import simplejson as json
else:
    import json
Aashutosh jha
quelle