我有一个Python模块,我想动态导入只给出一个模块名称的字符串。通常我使用importlib
或__import__
,这很有效,因为我知道要从模块导入哪些对象,但有没有办法动态地执行import *
的等效操作。还是有更好的方法?
我一般都知道使用import *
的不良做法,但我试图导入的模块是动态自动生成的,我无法知道包含我正在寻址的类的确切模块
感谢。
答案 0 :(得分:24)
将update
用于dicts:
globals().update(importlib.import_module('some.package').__dict__)
请注意,使用a_module.__dict__
与from a_module import *
不同,因为所有名称都是“导入的”,不仅是来自__all__
的名称,也不是_
开头的名称。
答案 1 :(得分:5)
我想出了一些丑陋的hacky代码,它在python 2.6中运行。我不确定这是否是最聪明的事情,也许这里的其他人也有一些见解:
test = __import__('os',globals(),locals())
for k in dir(test):
globals()[k] = test.__dict__[k]
您可能希望在此处进行检查,以确保您不会覆盖全局命名空间中的任何内容。您可以避免全局部分,只需查看每个动态导入的模块,以获得您感兴趣的类。这可能比使用您导入的所有内容污染全局命名空间要好得多。
例如,假设您的类名为来自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')
答案 2 :(得分:3)
以下是高度罪恶的,并会谴责你炼狱或更糟糕
# module A
myvar = "hello"
# module B
import inspect
def dyn_import_all(modpath):
"""Incredibly hackish way to load into caller's global namespace"""
exec('from ' + modpath + ' import *', inspect.stack()[1][0].f_globals)
# module C
from module B import dyn_import_all
def print_from(modpath):
dyn_import_all(modpath)
print(myvar)