如何在python中有选择地导入模块?

Thu*_*rEX 7 python coding-style

我有几个不同的模块,我需要根据不同的情况导入其中一个,例如:

if check_situation() == 1:
    import helper_1 as helper
elif check_situation() == 2:
    import helper_2 as helper
elif ...
    ...
else:
    import helper_0 as helper
Run Code Online (Sandbox Code Playgroud)

这些助手含有相同的词典dict01,dict02,dict03...但在不同的情况下,被称为不同的值.

但这有一些问题:

  1. 导入句子都写在文件的顶部,但check_situation()这里的函数需要先决条件,所以它现在远离顶层.
  2. 超过1个文件需要这个帮助器模块,所以使用这种导入是困难和丑陋的.

那么,如何重新安排这些助手呢?

Ash*_*ary 5

您可以使用__import__(),它接受一个字符串并返回该模块:

helper=__import__("helper_{0}".format(check_situation()))
Run Code Online (Sandbox Code Playgroud)

例子 :

In [10]: mod=__import__("{0}math".format(raw_input("enter 'c' or '': ")))
enter 'c' or '': c             #imports cmath

In [11]: mod.__file__
Out[11]: '/usr/local/lib/python2.7/lib-dynload/cmath.so'

In [12]: mod=__import__("{0}math".format(raw_input("enter 'c' or '': ")))
enter 'c' or '': 

In [13]: mod.__file__
Out[13]: '/usr/local/lib/python2.7/lib-dynload/math.so'
Run Code Online (Sandbox Code Playgroud)

正如@wim 和 python3.x 文档所指出的__import__()

导入一个模块。由于此函数旨在供 Python 解释器使用而不是一般用途,因此最好用于 importlib.import_module()以编程方式导入模块。

  • -1 因为阅读 `__import__` 的文档字符串 - _"这个函数是供 Python 解释器使用而不是用于一般用途,最好使用 importlib.import_module() 以编程方式导入模块"_ (2认同)

wim*_*wim 5

首先,没有严格的要求 import 语句必须在文件的顶部,它更像是一个样式指南。

现在,importlibadict可用于替换您的if/elif链:

import importlib

d = {1: 'helper_1', 2: 'helper_2'}
helper = importlib.import_module(d.get(check_situation(), 'helper_0'))
Run Code Online (Sandbox Code Playgroud)

但这只是语法糖,我怀疑你有更大的鱼要煎。听起来您需要重新考虑您的数据结构,并重新设计代码。

任何时候你有像dict01,一样的变量dict02dict03这是一个明确的信号,你需要提升一个级别,并有一些容器,dicts例如它们的列表。以数字结尾的“助手”模块名称也是如此。


Thu*_*rEX 1

自己解决,参考@Michael Scott Cuthbert

# re_direct.py

import this_module
import that_module

wanted = None


# caller.py
import re-direct

'''
many prerequisites
'''
def imp_now(case):
    import re_direct
    if case1:
        re_direct.wanted = re_direct.this_module
    elif case2:
        re_direct.wanted = re_direct.that_module
Run Code Online (Sandbox Code Playgroud)

然后,如果在调用者中,我调用该imp_now,那么无论是在调用者文件中调用还是在其他文件中调用这个想要的,都将被重定向到this_or_that_module。

另外,因为我只在函数中导入 re_direct ,所以你不会在其他地方看到这个模块,而只会看到想要的。