Python: 使用 importlib 从字符串中动态导入模块的代码
Python: Dynamically import module's code from string with importlib
我希望在 Python (3.7) 中动态导入一个模块,其中模块的代码是在一个字符串中定义的。
下面是一个使用 imp
模块的工作示例,该模块已被弃用,取而代之的是 importlib
(从版本 3.4 开始):
import imp
def import_code(code, name):
# create blank module
module = imp.new_module(name)
# populate the module with code
exec(code, module.__dict__)
return module
code = """
def testFunc():
print('spam!')
"""
m = import_code(code, 'test')
m.testFunc()
Python 的文档指出应该使用 importlib.util.module_from_spec()
而不是 imp.new_module()
。但是,似乎没有办法使用 importlib
模块创建空白模块对象,就像我可以使用 imp
.
如何使用 importlib
而不是 imp
来获得相同的结果?
你可以简单地实例化types.Module
:
import types
mod = types.ModuleType("mod")
然后你可以用 exec
填充它,就像你做的那样:
exec(code, mod.__dict__)
mod.testFunc() # will print 'spam!'
因此您的代码将如下所示:
import types
def import_code(code, name):
# create blank module
module = types.ModuleType(name)
# populate the module with code
exec(code, module.__dict__)
return module
code = """
def testFunc():
print('spam!')
"""
m = import_code(code, 'test')
m.testFunc()
正如@Error - Syntactical Remorse 所评论的那样,您应该记住 exec
基本上执行您提供的字符串中包含的任何代码,因此您应该格外小心地使用它。
至少检查一下你得到的是什么,但最好只使用预定义的字符串。
根据 Python 文档 module_from_spec()
importlib.util.module_from_spec(spec)
...
This function is preferred over using types.ModuleType to create a new module as spec is used to set as many import-controlled attributes on the module as possible.
这是我从 github 存储库中的源代码加载模块的想法。这是一种无需将文件写入磁盘的方法。
import requests
url = "https://github.com/udacity/deep-learning-v2-pytorch/raw/master/intro-to-pytorch/helper.py"
r = requests.get(url)
import importlib.util
spec = importlib.util.spec_from_loader('helper', loader=None, origin=url)
helper = importlib.util.module_from_spec(spec)
exec(r.content, helper.__dict__)
helper.view_classify() # executes function from github file
我希望在 Python (3.7) 中动态导入一个模块,其中模块的代码是在一个字符串中定义的。
下面是一个使用 imp
模块的工作示例,该模块已被弃用,取而代之的是 importlib
(从版本 3.4 开始):
import imp
def import_code(code, name):
# create blank module
module = imp.new_module(name)
# populate the module with code
exec(code, module.__dict__)
return module
code = """
def testFunc():
print('spam!')
"""
m = import_code(code, 'test')
m.testFunc()
Python 的文档指出应该使用 importlib.util.module_from_spec()
而不是 imp.new_module()
。但是,似乎没有办法使用 importlib
模块创建空白模块对象,就像我可以使用 imp
.
如何使用 importlib
而不是 imp
来获得相同的结果?
你可以简单地实例化types.Module
:
import types
mod = types.ModuleType("mod")
然后你可以用 exec
填充它,就像你做的那样:
exec(code, mod.__dict__)
mod.testFunc() # will print 'spam!'
因此您的代码将如下所示:
import types
def import_code(code, name):
# create blank module
module = types.ModuleType(name)
# populate the module with code
exec(code, module.__dict__)
return module
code = """
def testFunc():
print('spam!')
"""
m = import_code(code, 'test')
m.testFunc()
正如@Error - Syntactical Remorse 所评论的那样,您应该记住 exec
基本上执行您提供的字符串中包含的任何代码,因此您应该格外小心地使用它。
至少检查一下你得到的是什么,但最好只使用预定义的字符串。
根据 Python 文档 module_from_spec()
importlib.util.module_from_spec(spec)
...
This function is preferred over using types.ModuleType to create a new module as spec is used to set as many import-controlled attributes on the module as possible.
这是我从 github 存储库中的源代码加载模块的想法。这是一种无需将文件写入磁盘的方法。
import requests
url = "https://github.com/udacity/deep-learning-v2-pytorch/raw/master/intro-to-pytorch/helper.py"
r = requests.get(url)
import importlib.util
spec = importlib.util.spec_from_loader('helper', loader=None, origin=url)
helper = importlib.util.module_from_spec(spec)
exec(r.content, helper.__dict__)
helper.view_classify() # executes function from github file