9

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

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

这些助手包含相同的字典dict01, dict02, dict03...但在不同情况下调用的值不同。

但这有一些问题:

  1. 导入语句都写在文件的顶部,但是check_situation()这里的函数需要先决条件,所以它现在离顶部很远。
  2. 超过 1 个文件需要这个辅助模块,所以使用这种导入既难又难看。

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

4

4 回答 4

5

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

helper=__import__("helper_{0}".format(check_situation()))

例子 :

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'

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

导入一个模块。因为这个函数是供 Python 解释器使用的,而不是一般用途,所以最好使用 importlib.import_module()以编程方式导入模块。

于 2013-03-13T03:00:01.123 回答
5

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

现在,importlibadict可以用来替换你的if/elif链:

import importlib

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

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

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

于 2013-03-13T03:06:30.163 回答
1

我同意其他答案中给出的方法更接近您标题中提出的主要问题,但是如果导入模块的开销很低(因为可能导入几个字典)并且导入没有副作用,在这种情况下,您最好将它们全部导入并稍后在模块中选择正确的字典:

import helper_0
import helper_1
...
helperList = [helper_0, helper_1, helper_2...]
...
helper = helperList[check_situation()]
于 2013-03-13T03:31:24.020 回答
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

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

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

于 2013-03-13T09:06:54.130 回答