2017-06-12 56 views
8

正如讨论的here,我们可以使用字符串变量动态地导入模块。Python动态导入 - 如何从变量的模块名称中导入*

import importlib 
importlib.import_module('os.path') 

我的问题是如何从字符串变量import *

一些像这样的事情没有工作,现在

importlib.import_module('os.path.*') 
+1

你为什么要这么做? ''''''进口通常是不被接受的,它们混乱了命名空间,你最终可能会导入你不想要的东西(例如,模块被更新,获得覆盖先前导入的新函数)。你有动态地做这件事的具体用例吗? – mata

+0

我知道用'import *'听起来很危险;尽管它适用于简单的用例。我的具体用例是,我试图用'proboscis'来运行'python test',它允许我选择运行哪个测试套装 - 所选择的测试套装是由一组测试文件名定义的。 –

回答

14

你可以做下面的技巧:

>>> import importlib 
>>> globals().update(importlib.import_module('math').__dict__) 
>>> sin 
<built-in function sin> 

被警告,使所有的名称可用的模块在本地,所以它是略有不同比*,因为它不是以__all__开始,所以对于例如它也将覆盖__name__,__package__,__loader__,__doc__

更新:

这里是@mata在comments指出了一个更精确,更安全的版本:

module = importlib.import_module('math') 

globals().update(
    {n: getattr(module, n) for n in module.__all__} if hasattr(module, '__all__') 
    else 
    {k: v for (k, v) in module.__dict__.items() if not k.startswith('_') 
}) 

特别感谢南摹VU的协助,让答案更完整。

+0

我不明白'它与*有些不同,因为它不以__all__开始 - 它是什么**它在这里? –

+2

这也会导入诸如'__name__','__package__','__loader__','__doc__'等你绝对不想导入的东西。 – mata

+5

不止是一个罪 – hurturk