31

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

4

4 回答 4

48

看起来这应该可以解决问题:导入动态生成的模块

>>> 进口小鬼
>>> 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'...>
>>>
于 2010-09-26T20:13:35.690 回答
5

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

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

于 2010-09-26T20:15:58.553 回答
0

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

我想出了以下

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 导入,如果您

于 2021-08-15T04:41:23.273 回答
0

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

于 2021-04-18T19:49:28.463 回答