我有一个 Python 模块,我只想动态导入一个模块名称字符串。通常我使用importlib
or__import__
并且考虑到我知道要从模块导入哪些对象,这非常有效,但是有没有办法import *
动态地做等效的操作。还是有更好的方法?
我通常知道使用它的坏习惯,import *
但是我尝试导入的模块是动态自动生成的,我无法知道包含我正在处理的类的确切模块。
谢谢。
我有一个 Python 模块,我只想动态导入一个模块名称字符串。通常我使用importlib
or__import__
并且考虑到我知道要从模块导入哪些对象,这非常有效,但是有没有办法import *
动态地做等效的操作。还是有更好的方法?
我通常知道使用它的坏习惯,import *
但是我尝试导入的模块是动态自动生成的,我无法知道包含我正在处理的类的确切模块。
谢谢。
用于update
听写:
globals().update(importlib.import_module('some.package').__dict__)
请注意, usinga_module.__dict__
与 不同from a_module import *
,因为所有名称都是“导入”的,而不仅仅是那些 from__all__
或不以 . 开头的名称_
。
我想出了一些丑陋的hacky代码,它适用于python 2.6。我不确定这是否是最聪明的做法,也许这里的其他一些人有一些见解:
test = __import__('os',globals(),locals())
for k in dir(test):
globals()[k] = test.__dict__[k]
您可能想在此处检查以确保您没有覆盖全局名称空间中的任何内容。您可能可以避免使用全局部分,而只需查看您感兴趣的类的每个动态导入的模块。这可能比使用您正在导入的所有内容污染全局名称空间要好得多。
例如,假设您的课程名为 Request from 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')
以下是非常有罪的,会让你进入炼狱或更糟糕的境地
# module_a.py
myvar = "hello"
# module_b.py
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.py
from module_b import dyn_import_all
def print_from(modpath):
dyn_import_all(modpath)
print(myvar)
演示:
>>> import module_c
>>> module_c.print_from("module_a")
hello