【问题标题】:Dynamically importing Python module动态导入 Python 模块
【发布时间】:2011-04-17 12:08:07
【问题描述】:

我有一个存储许多自定义 Python 模块的可信远程服务器。我可以通过 HTTP(例如使用urllib2.urlopen)以文本/纯文本形式获取它们,但我无法将获取的模块代码保存到本地硬盘。如何将代码导入为完全可操作的 Python 模块,包括其全局变量和导入?
我想我必须使用execimp 模块功能的某种组合,但我还不能让它工作。

【问题讨论】:

  • 您是通过 ssl 下载它们还是每个中间路由器都受信任? :P
  • 实际上,是的 - 模块存储和前端服务器都是单个系统的一部分(甚至位于同一个服务器机房中)。现在,假设没有安全隐患:即使我通过 SSL 下载代码,如何解释它的问题仍然存在。

标签: python dynamic-import


【解决方案1】:

看起来应该可以解决问题:importing a dynamically generated module

>>> 进口小鬼 >>> foo = imp.new_module("foo") >>> foo_code = """ ...类Foo: ... 经过 ……“”“ >>> 在 foo.__dict__ 中执行 foo_code >>> foo.Foo.__module__ “富” >>>

此外,正如 ActiveState 文章中所建议的,您可能希望将新模块添加到 sys.modules

>>> 导入系统 >>> sys.modules["foo"] = foo >>> 从 foo 导入 Foo >>>

【讨论】:

  • 有什么技巧可以让用户“从 foo 导入 Foo”吗?在这个例子中,我得到“ImportError: No module named foo”。
  • sys.modules["foo"] = foo 之后,sys 模块中断并等于None。这是应该发生的还是可以避免的?请参阅我的问题here
  • @DavidWolever 似乎 imp.new_module 自 Python 3.4 (ref) 以来已被弃用。请改用importlib.util.module_from_spec
【解决方案2】:

这是我不久前收藏的内容,涵盖了类似的内容:

这有点超出你想要的,但基本的想法就在那里。

【讨论】:

    【解决方案3】:

    Python3版本
    (尝试编辑其他答案但编辑队列已满)

    import imp
    
    my_dynamic_module = imp.new_module("my_dynamic_module")
    exec("""
    class Foo:
        pass
    """, my_dynamic_module.__dict__)
    
    Foo = my_dynamic_module.Foo
    foo_object = Foo()
    
    # register it on sys
    import sys
    sys.modules[my_dynamic_module.__name__] = my_dynamic_module
    
    

    【讨论】:

      【解决方案4】:

      我最近在尝试为我放入项目自述文件中的源代码示例编写单元测试时遇到了这种情况(我想避免只是链接到小文件或以可能不同步的方式复制文本) .

      我想出了以下内容

      import sys
      import types
      from importlib import import_module
      
      
      def compile_and_install_module(module_name: str, source_code: str) -> types.ModuleType:
          """Compile source code and install it as a module.
      
          End result is that `import <module_name>` and `from <module_name> import ...` should work.
          """
          module = types.ModuleType(module_name, "Module created from source code")
      
          # Execute source in context of empty/fake module
          exec(source_code, module.__dict__)
      
          # Insert fake module into sys.modules. It's now a real module
          sys.modules[module_name] = module
      
          # Imports should work now
          return import_module(module_name)
      

      以及如何使用它的快速示例

      $ cat hello.py 
      def foo():
          print("Hello world")
      
      
      bar = 42
      
      $ python
      Python 3.9.5 (tags/v3.9.5:0a7dcbd, May  3 2021, 17:27:52) [MSC v.1928 64 bit (AMD64)] on win32
      Type "help", "copyright", "credits" or "license" for more information.
      >>> from compile import compile_and_install_module
      >>> compile_and_install_module("hello", open("hello.py").read())
      <module 'hello'>
      >>> import hello
      >>> hello.foo()
      Hello world
      >>> from hello import bar
      >>> bar
      42
      

      如果你可以删除返回值和import_lib导入

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-06
        • 2013-03-25
        • 1970-01-01
        • 2020-07-25
        • 2023-02-01
        相关资源
        最近更新 更多