【问题标题】:Load Python source/binary without adding to sys.modules加载 Python 源代码/二进制文件而不添加到 sys.modules
【发布时间】:2013-03-06 19:09:20
【问题描述】:

我想加载 Python 代码(如果可能的话,使用任意文件扩展名,甚至从内存、源代码或二进制文件)而不将其添加到 sys.modules。使用imp.load_source 可以加载文件,但返回的模块会添加到sys.modules,甚至可能与现有模块连接(参见this question)!

所以,我目前正在做的是使用 __import__() 内置。虽然它允许我从包中导入,但我无法加载任意文件。

try:
    m = __import__(name)
    for n in name.split('.')[1:]:
        m = getattr(m, n)
    return m
except:
    raise
finally:
    # Restore the old module configuration. Only modules that have
    # not been in sys.path before will be removed.
    for k, v in sys.modules.items():
        if k not in prev_modules and self.is_local(v) or not v:
            del sys.modules[k]
        else:
            sys.modules[k] = v
  1. 在导入之前删除所有未进入的模块对我来说是一种非常老套的方法。
  2. 当同名模块已经存在时,不会重新加载。
  3. 我无法加载任意文件,甚至无法从内存中加载。

出于安全原因,我试图避免使用exec 语句。由exec 评估的源可以使用sys._getframe() 侵入我的应用程序(当然还有更多的可能性)。我查看了 django load 标签的实现,但也只使用了__import_()

有没有办法从安全、独立的文件(甚至内存)中加载 Python 代码(源代码或二进制代码)(不添加与 sys.modules 的交互)?在最好的情况下,它不仅可以让我从内存中加载文件,还可以加载像__import__() 函数这样的完整包。

【问题讨论】:

  • 我认为secureself-contained 这个词在这里是不可能的组合。 AFAIK,导入 python 模块可以有效地执行它。我知道的最接近的是seattle.cs.washington.edu/browser/seattle/branches/repy_v2/repy/…,它试图构建一个安全的执行器。它基于静态分析代码并删除对“危险”内置程序的访问。

标签: python dynamic import module


【解决方案1】:

使用 CPython 解释器,我不相信这是可能的。然而,PyPy 提供了一个沙盒环境,让您想做的事情变得非常容易。

Look at the PyPy documentation on sandboxing for details.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-12
    • 1970-01-01
    • 1970-01-01
    • 2012-06-08
    • 2019-05-01
    相关资源
    最近更新 更多