【问题标题】:Change environment variables before importlib.reload在 importlib.reload 之前更改环境变量
【发布时间】:2017-03-13 15:32:28
【问题描述】:

我有一个在静态初始化期间加载环境变量的 c 扩展。我需要能够更改这些值并重新加载模块(我无法更改它们是静态加载的事实)。我尝试设置os.environ,但importlib 中似乎没有env 选项,例如subprocess.call

这是一个例子:假设我有一个如下定义的模块

#include <boost/python.hpp>
#include <cstdlib>
#include <string>
std::string get() {
    return ::getenv("HOME");
}

BOOST_PYTHON_MODULE(sample) {
    boost::python::def("get", &get);
}

我有 python 代码:

import importlib, os
import sample as s
print(s.get()) # prints /home/username

# do something like 
# os.environ['HOME'] = 'foo'
importlib.reload(s)
print(s.get()) # I would like this to print 'foo'

也就是说,除了os.environ['HOME'] = 'foo',我还能做什么来导致c模块中的环境变量发生变化?

注意:我不能使用setenv,因为变量是静态加载的,我无法重新初始化所有依赖它们的东西。

【问题讨论】:

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


    【解决方案1】:

    如果我没记错的话,这不起作用的原因不是因为没有修改环境,而是因为当你这样做时importlib.reload(s)the c module is not actually re-initialized

    您可以做的是将您对 s 的调用放在另一个进程中,并在您需要重新加载它时创建一个新进程。

    【讨论】:

    • 您是正确的,c 模块实际上并未重新初始化。我宁愿不创建新进程,因为我首先创建 c 模块的原因是为了避免这样做。
    • @JRG 如果可以的话,你想用这个 c 扩展来实现什么?显然,您不是在尝试读取环境变量,因为如果是这种情况,您可以在 python 端执行它而不使用 c 扩展。如果有更大的目标,那么也许您可以避免使用环境变量进行通信并使用其他东西
    【解决方案2】:

    也许您可以在您的或第二个 c 扩展中使用 Py_Finalize 和 Py_Initialize 来代替您的模块重新加载?但这可能有点矫枉过正......?

    【讨论】:

    • 这是个好主意,但是我必须为我的 c++ 代码创建 c 绑定才能导出到第二个 .so。
    猜你喜欢
    • 2014-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多