Warunkowy import modułów w Pythonie

140

W moim programie chcę zaimportować simplejson lub json w zależności od tego, czy system operacyjny, na którym pracuje użytkownik, to Windows czy Linux. Biorę nazwę systemu operacyjnego jako dane wejściowe od użytkownika. Czy teraz należy wykonać następujące czynności?

osys = raw_input("Press w for windows,l for linux")
if (osys == "w"):
    import json as simplejson
else:
    import simplejson  
Tim
źródło
33
Dlaczego pobierasz nazwę systemu operacyjnego jako dane wejściowe od użytkownika? Zajrzyj do modułu platformy. docs.python.org/library/platform.html platform.platform() lub platform.system()powinien zrobić to, czego potrzebujesz, zamiast zmuszać użytkownika do wprowadzania czegoś za każdym razem, gdy kod jest uruchamiany.
Joe Kington
56
@ S.Lott: poważnie? Wiesz, że głosy w górę / w dół mają odzwierciedlać jakość pytania , prawda? I nie to, czy zgadzasz się z czymś innym w kodzie OP.
jalf
2
@jalf: To złe pytanie pod każdym względem, z wyjątkiem gramatyki. Nie należy go traktować jako pierwszej odpowiedzi na jakiekolwiek wyszukiwanie.
S.Lott
11
@ S.Lott nie ma nic złego w tym, że chce się wiedzieć, czy importy warunkowe są pythonowe. I oczywiście inni się z tym zgadzają, ponieważ pomimo twoich wysiłków ma on +50 głosów.
SARose
5
+1 dla koncepcji, której szukałem (importuj tylko, jeśli używasz Win); i kolejne koncepcyjne +1, aby zrekompensować absurdalne głosowanie przeciw.
S3DEV

Odpowiedzi:

182

Widziałem często używany ten idiom, więc nie musisz nawet wąchać systemu operacyjnego:

try:
    import json
except ImportError:
    import simplejson as json
Matt Williamson
źródło
17
Najpierw należy spróbować zaimportować, simplejson as jsonponieważ jest to prawdopodobnie nowsza (szybsza) wersja standardowego jsonmodułu.
Seppo Erviälä
lub ujsondla szybkości
lababidi
59

Aby odpowiedzieć na pytanie w twoim tytule, ale nie na konkretny przypadek, który podasz, jest całkowicie poprawny, robi to mnóstwo paczek. Prawdopodobnie lepiej jest samodzielnie wymyślić system operacyjny, zamiast polegać na użytkowniku; tutaj pySerial robi to jako przykład.

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

Powinno to być używane tylko w przypadkach, gdy zakładasz i potrzebujesz silnej gwarancji, że będą tam określone interfejsy / funkcje: np. Wywołano „plik” /dev/ttyX. W twoim przypadku: mając do czynienia z JSON, nie ma nic, co jest specyficzne dla systemu operacyjnego, a ty sprawdzasz tylko, czy pakiet istnieje, czy nie. W takim przypadku wystarczy trygo zaimportować, a exceptjeśli się nie powiedzie, skorzystaj z opcji:

try:
    import some_specific_json_module as json
except ImportError:
    import json
Nick T.
źródło
11
Nie, to jest bardzo błędne nazwy hardcode OS zdecydować, czy simplejsonczy jsonjest dostępny. Cytujesz kod z importu nieodłącznie specyficznego dla systemu operacyjnego , co jest zupełnie innym przypadkiem. Zobacz odpowiedź Matta, aby poznać właściwe podejście.
Glenn Maynard
16
@Glenn Maynard: W takim razie zwlekałbym z tobą; Nigdy nie korzystałem z tego jsonpakietu i próbowałem odpowiedzieć na bardziej ogólne pytanie „czy możesz dokonać warunkowego importu modułów”.
Nick T
7

Nie zaleca się używania do łączenia json lub simplejson z platformą systemu operacyjnego. simplejson jest nowszą i zaawansowaną wersją json, więc powinniśmy najpierw spróbować ją zaimportować.

W oparciu o wersję Pythona możesz spróbować poniżej sposobu importowania json lub simplejson

import sys
if sys.version_info > (2, 7):
    import simplejson as json
else:
    import json
Aashutosh jha
źródło