代码之家  ›  专栏  ›  技术社区  ›  ThunderEX

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

  •  9
  • ThunderEX  · 技术社区  · 13 年前

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

    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个文件需要这个helper模块,所以使用这种导入既困难又难看。

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

    4 回复  |  直到 13 年前
        1
  •  5
  •   wim    13 年前

    首先,没有严格要求导入语句必须位于文件的顶部,这更多的是一个样式指南。

    现在 importlib 和一个 dict 可以用来替换您的 if / elif 链条:

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

    但这只是句法上的糖,真的,我怀疑你还有更大的事情要做。听起来你需要重新考虑你的数据结构,并重新设计代码。

    任何时候您都可以将变量命名为 dict01 , dict02 , dict03 这是一个确定的迹象,表明你需要提高一个级别,并拥有一些容器 dicts 例如它们的列表。以数字结尾的“helper”模块名称也是如此。

        2
  •  5
  •   Ashwini Chaudhary    13 年前

    您可以使用 __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上的docs所指出的那样 __导入__() :

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

        3
  •  1
  •   ThunderEX    13 年前

    我自己解决,参考@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,那么want,无论在调用者文件中调用还是在其他调用该want的文件中调用,都将被重定向到this_or_that_module。

    此外,因为我只在函数中导入re_direct,所以您不会在其他任何地方看到这个模块,而只能看到所需的。

        4
  •  1
  •   Michael Scott Asato Cuthbert    13 年前

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

    import helper_0
    import helper_1
    ...
    helperList = [helper_0, helper_1, helper_2...]
    ...
    helper = helperList[check_situation()]