Умовний імпорт модулів у Python


140

У своїй програмі я хочу імпортувати simplejson або json, залежно від того, чи є ОС, якою користувач є Windows чи Linux. Я приймаю ім'я ОС як вхід від користувача. Тепер, чи правильно робити наступне?

osys = raw_input("Press w for windows,l for linux")
if (osys == "w"):
    import json as simplejson
else:
    import simplejson  

33
Чому ви берете ім'я os як вхід від користувача? Загляньте в модуль платформи. docs.python.org/library/platform.html platform.platform() або platform.system()робити все, що вам потрібно, а не користувачеві доводиться щось вводити щоразу при запуску коду.
Джо Кінгтон

56
@ S.Lott: серйозно? Ви знаєте, що вгору / знизу покликані відображати якість питання , правда? І не чи згодні ви з чимось іншим у коді ОП.
jalf

2
@jalf: Це поганий питання будь-яким способом, крім граматики. Його не слід розглядати як найкращу відповідь на будь-який вид пошуку.
S.Lott

11
@ S.Lott немає нічого поганого у бажанні знати, чи умовний імпорт є пітонічним. І очевидно, що інші погоджуються, оскільки він не має 50 голосів, незважаючи на ваші зусилля.
SARose

5
+1 за концепцією, яку я шукав (імпортуйте лише, якщо використовуєте Win); та ще одна концептуальна оцінка +1 для компенсації смішного голосування.
S3DEV

Відповіді:


182

Я бачив, як ця ідіома використовувалася багато, тому вам навіть не доведеться робити нюхання ОС:

try:
    import json
except ImportError:
    import simplejson as json

17
Спочатку слід спробувати імпортувати, simplejson as jsonоскільки це, швидше за все, новіша (швидша) версія стандартного jsonмодуля.
Seppo Erviälä

або ujsonдля швидкості
lababidi

59

Щоб відповісти на запитання у вашій назві, але не в конкретному випадку, який ви вказали, це цілком правильно, тонни пакетів це роблять. Напевно, краще самостійно з'ясувати ОС, а не покладатися на користувача; ось pySerial це робить як приклад.

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

Це слід використовувати лише в тих випадках, коли ви припускаєте, що вам потрібна чітка гарантія, що певні інтерфейси / функції будуть наявні: наприклад, "файл", який називається /dev/ttyX. У вашому випадку: маючи справу з JSON, насправді немає нічого, що стосується ОС, і ви лише перевіряєте, чи існує пакет чи ні. У такому випадку просто tryімпортувати його, і відновлювати, exceptякщо він не вдається:

try:
    import some_specific_json_module as json
except ImportError:
    import json

11
Ні, це дуже неправильно імена жорстко OS вирішити , буде чи simplejsonабо jsonдоступний. Ви цитуєте код, притаманний імпорту, специфічному для ОС. Це дуже інший випадок. Дивіться відповідь Метта щодо правильного підходу.
Гленн Мейнард

16
@ Гленн Мейнард: Я б тоді відказав вам; Я ніколи не використовував jsonпакет і намагався відповісти на більш загальне питання "чи можна робити умовний імпорт модулів".
Нік Т

7

Не рекомендується використовувати для прив'язки json або simplejson з платформою ОС. simplejson - це новіша і вдосконалена версія json, тому ми повинні спробувати імпортувати її спочатку.

На основі версії python ви можете спробувати нижче спосіб імпорту json або simplejson

import sys
if sys.version_info > (2, 7):
    import simplejson as json
else:
    import json
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.