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  

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

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

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.