【问题标题】:Python: Dynamically import module's code from string with importlibPython:使用 importlib 从字符串动态导入模块的代码
【发布时间】:2019-04-29 14:14:39
【问题描述】:

我希望在 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 来获得相同的结果?

【问题讨论】:

    标签: python python-3.x python-importlib dynamic-import


    【解决方案1】:

    你可以简单地实例化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 基本上会执行您给它的字符串中包含的任何代码,因此您应该格外小心地使用它。 至少检查一下你得到了什么,但最好使用专门的预定义字符串。

    【讨论】:

    • 您可能需要添加一个免责声明,即他只能使用预先指定的strs 或在调用exec 方法之前检查它们。
    • @Error-SyntacticalRemorse 你说得对,我加了一个旁注
    【解决方案2】:

    根据 Python 文档module_from_spec()

    importlib.util.module_from_spec(spec)

    ...

    此函数优于使用 types.ModuleType 创建新模块,因为 spec 用于在模块上设置尽可能多的导入控制属性。

    这是我想出的从位于 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
    

    【讨论】:

    • 正是我想要的
    猜你喜欢
    • 2021-12-03
    • 1970-01-01
    • 2018-11-25
    • 2019-10-30
    • 2023-03-08
    • 1970-01-01
    • 2022-01-05
    • 2014-11-07
    相关资源
    最近更新 更多