Условный импорт модулей в 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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.