从模块动态导入所有内容(*)

Ste*_*ehl 23 python import python-module

我有一个Python模块,我想动态导入只给出一个模块名称的字符串.通常我使用importlib或者__import__这很好用,因为我知道我想从模块导入哪些对象,但是有没有办法import *动态地做同样的事情.还是有更好的方法?

我一般都知道使用它的不良做法,import *但我试图导入的模块是动态自动生成的,我无法知道包含我正在寻址的类的确切模块.

谢谢.

war*_*iuc 26

使用update的类型的字典:

globals().update(importlib.import_module('some.package').__dict__)
Run Code Online (Sandbox Code Playgroud)

请注意,使用a_module.__dict__不一样from a_module import *,因为所有名称都是"导入"的,不仅是那些来自__all__或不是以_.

  • 这比GWW的答案略好,因为它使用更新而不是模块上的迭代. (5认同)

GWW*_*GWW 5

我提出了一些丑陋的hacky代码,它适用于python 2.6.我不确定这是否是最聪明的事情,也许这里的其他人也有一些见解:

test = __import__('os',globals(),locals())
for k in dir(test):
    globals()[k] = test.__dict__[k]
Run Code Online (Sandbox Code Playgroud)

您可能希望在此处检查以确保您不会覆盖全局命名空间中的任何内容.您可以避免全局部分,只需查看每个动态导入的模块,以获得您感兴趣的类.这可能比使用您导入的所有内容污染全局命名空间要好得多.

例如,假设您的类名为来自urllib2的请求

test = __import__('urllib2',globals(),locals())
cls = None
if 'Request' in dir(test):
    cls = test.__dict__['Request']
    # you found the class now you can use it!
    cls('http://test.com')
Run Code Online (Sandbox Code Playgroud)

  • 实际上这并不比yoyu想象的那么迟钝 - 它与"from <module> import*"具有完全相同的效果 - 正如这句话所做的那样是更新当前的全局字典.这是通过调用globals()恢复的相同字典.至于"检查",你警告OP:注意"import*"本身只是覆盖了一切:-) (2认同)
  • @freyirs:注意如果它放在一个本身从另一个模块导入的函数中,这个代码将无法工作.因为函数在调用`globals()时检索的字典是模块的globals目录,而不是调用函数的上下文中的全局目录. (2认同)
  • @GWW:在这种情况下,“更优雅”不会尝试做“import *”所做的事情,因为这本身就相当不优雅。OP 应该考虑使用字典来存储这些内容,而不是让潜在的随机名称出现在执行范围中。 (2认同)