Умовний імпорт модулів у 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.