Условный импорт модулей в Python

141

В моей программе я хочу импортировать 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
Почему вы берете имя ОС в качестве ввода от пользователя? Посмотрите на модуль платформы. docs.python.org/library/platform.html platform.platform() или platform.system()следует делать то, что вам нужно, вместо того, чтобы пользователь должен был что-то вводить при каждом запуске кода.
Джо Кингтон
56
@ S.Lott: серьезно? Вы знаете, что отрицательные и отрицательные голоса предназначены для отражения качества вопроса , верно? И не согласны ли вы с чем - то еще в коде ОП.
Джалф
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модуля.
Сеппо Эрвиаля
или ujsonдля скорости
лабабиди
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
Нет, очень неправильно указывать имена ОС, чтобы решить, доступны они 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
Аашутош Джа
источник