有条件地在Python中导入模块

问题:有条件地在Python中导入模块

在我的程序中,我想基于用户所在的操作系统是Windows还是Linux来导入simplejson或json。我将操作系统名称作为用户的输入。现在,执行以下操作是否正确?

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

In my program I want to import simplejson or json based on whether the OS the user is on is Windows or Linux. I take the OS name as input from the user. Now, is it correct to do the following?

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

回答 0

我已经见过这个习惯用法很多,因此您甚至不必进行OS嗅探:

try:
    import json
except ImportError:
    import simplejson as json

I’ve seen this idiom used a lot, so you don’t even have to do OS sniffing:

try:
    import json
except ImportError:
    import simplejson as json

回答 1

要回答标题中的问题,而不是回答您提供的特殊情况,这是完全正确的,大量的软件包可以这样做。最好自己弄清楚操作系统,而不要依赖用户。这里以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,实际上没有任何特定于OS的内容,而您只是在检查软件包是否存在。在这种情况下,只需try导入即可,except如果失败则返回一个:

try:
    import some_specific_json_module as json
except ImportError:
    import json

To answer the question in your title but not the particular case you provide, it’s perfectly correct, tons of packages do this. It’s probably better to figure out the OS yourself instead of relying on the user; here’s pySerial doing it as an example.

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

This should be only used in cases where you’re assuming and need a strong guarantee that certain interfaces/features will be there: e.g. a ‘file’ called /dev/ttyX. In your case: dealing with JSON, there’s nothing that is actually OS-specific and you are only checking if the package exists or not. In that case, just try to import it, and fall-back with an except if it fails:

try:
    import some_specific_json_module as json
except ImportError:
    import json

回答 2

建议不要将json或simplejson与OS平台绑定。simplejson是json的更新和高级版本,因此我们应尝试首先将其导入。

基于python版本,您可以尝试以下方式导入json或simplejson

import sys
if sys.version_info > (2, 7):
    import simplejson as json
else:
    import json

It is not advisable to use to bind json or simplejson with OS platform. simplejson is newer and advanced version of json so we should try to import it first.

Based on python version you can try below way to import json or simplejson

import sys
if sys.version_info > (2, 7):
    import simplejson as json
else:
    import json