假设my_function()
位于my_apps.views中,我想动态导入my_function
,而不使用像exec
或eval
这样的东西。
有没有办法实现这个目标?我想要做类似于以下操作:
my_function = import_func("my_apps.views.my_function")
my_function()
... code is executed
你想要什么
my_function = getattr(__import__('my_apps.views'), 'my_function')
如果你在编译时知道函数的名称,你可以将其简化为:my_function = __import__('my_apps.views').my_function
这将加载my_apps.views
,然后将其my_function
属性分配给本地的my_function
。
如果你确定你只需要一个函数,那么这是可接受的。如果你想要多个属性,你可以这样做:
views = __import__('my_apps.views')
my_function = getattr(views, 'my_function')
my_other_function = getattr(views, 'my_other_function')
my_attribute = getattr(views, 'my_attribute')
这样更易读,能减少对 __import__
的调用。如果你知道名称,代码可以像上面那样缩短。
你也可以使用 imp 模块中的工具来实现,但它更加复杂。
Python 2.7
增加了importlib
模块,它提供了方便的包装器来使用__import__()
,并支持3.1版本的特性。
这个模块是Python 3.1中同名更全面的包的一个小子集,提供了完整的导入实现。这里提供的内容有助于从2.7过渡到3.1。
importlib.import_module(name, package=None)
导入一个模块。name参数指定要绝对或相对导入的模块名称(例如pkg.mod或..mod)。如果名称是相对的,则必须指定package参数以解析包名称的锚点(例如,import_module('..mod', 'pkg.subpkg')将导入pkg.mod)。指定的模块将被插入sys.modules并返回。
def import_by_string(full_name):
module_name, unit_name = full_name.rsplit('.', 1)
return getattr(__import__(module_name, fromlist=['']), unit_name)
exists = import_by_string("os.path.exists")
rsplit()
。使用module_name, unit_name = full_name.rsplit('.', 1)
比你现在所做的要高效得多。 - Anthon我刚刚写了这段代码,似乎很多人需要,所以即使以后我展示它也是有意义的。
def my_import(module_name,func_names = [],cache = False):
if module_name in globals() and cache:
return True
try:
m = __import__(module_name, globals(), locals(), func_names, -1)
if func_names:
for func_name in func_names:
globals()[func_name] = getattr(m,func_name)
else:
globals()[module_name] = m
return True
except ImportError:
return False
def my_imports(modules):
for module in modules:
if type(module) is tuple:
name = module[0]
funcs = module[1]
else:
name = module
funcs = []
if not my_import(name, funcs):
return module
return ''
def checkPluginsImports(plugin,modules):
c = my_imports(modules)
if c:
print plugin +" has errors!: module '"+c+"' not found"
# example: file test.py with "x" function
def d():
checkPluginsImports('demoPlugin',[('test',['x'])])
d()
x()
import importlib
modules = {
'module1': ('func1', 'func2'),
'module2': ('func3', 'func4', 'func5')}
imported_func = dict()
for module in modules.keys():
imported_module = importlib.import_module(module)
for sub_module in modules[module]:
imported_func[sub_module] = getattr(imported_module, sub_module)
# Usage
x = imported_func['func1']() # Insert the required arguments in the parenthesis
使用标准库pkg_resources
from pkg_resources import EntryPoint
my_function = EntryPoint.parse("my_function=my_apps.views:my_function").load(require=False)
我们有四种情况,取决于模块
和/或函数
是否固定:
module
名称是固定的字符串,function
名称也是固定的字符串:
my_function = __import__('my_apps.views', fromlist=['my_function'].my_function
(虽然在这种情况下使用 from my_app.views import my_function
更为简单)module
名称是固定的字符串,function
名称是变量:
function_name = ...
.
.
.
my_function = getattr(__import__('my_apps.views', fromlist=[function_name]),
function_name)
module
名称是变量,function
名称是固定的字符串:
module_name = ...
.
.
.
my_function = __import__(module_name, fromlist=['my_function']).my_function
module
名称是变量,function
名称也是变量:
module_name = ...
.
.
.
function_name = ...
.
.
.
my_function = getattr(__import__(module_name, fromlist=[function_name]),
function_name)
__import__
关键字参数fromlist
时,返回的是包根目录而不是模块。对于所有非空列表,返回实际的模块。
my_function = __import__('my_apps.views', globals(), locals(), ['my_function']).my_function
参见 Python 文档关于 import 的说明。 - marcomy_apps
而不是my_apps.views
导入该函数。 - oarfish