是否可以在运行时修改PYTHONPATH?

2024-04-25 11:47:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个C++应用程序,动态连接到Python解释器。我希望能够从特定目录导入python模块。我想修改进程的PYTHONPATH,以便sys.path包含我添加到PYTHONPATH的路径。根据本文档,这似乎是它的工作方式:

http://docs.python.org/c-api/intro.html#embedding-python

但是,当我从Python land打印sys.path时,它具有PYTHONPATH的原始内容,而不是我设置的内容。下面是我正在做的一个例子(使用Boost.Python):

int main(int argc, char* argv[])
{
  _putenv_s("PYTHONPATH", "C:\\source\\\\modules");
  Py_Initialize();
  object main = import("__main__");
  object global = (main.attr("__dict__"));
  exec("import sys\nprint sys.path"), global, global);
}

我知道还有其他方法可以达到我的目标,但这不是我想要的。我想知道为什么Py_Initialize()在设置sys.path时不使用PYTHONPATH的当前值。或者我误解了它的工作原理?


Tags: pathpyimport目录应用程序内容objectmain
3条回答

如果一次使用多个C运行库,就会发生这种情况。在这种情况下,应用程序和Python DLL可能链接到不同的crt。每个CRT都有自己的一组环境变量;从一个CRT使用putenv对环境所做的更改在使用不同CRT进行的getenv调用中不可见。

请参阅http://msdn.microsoft.com/en-us/library/ms235460%28v=vs.80%29.aspx上的“readEnv”示例。

你可以通过确保只使用一个CRT来解决这个问题,但这在实践中是很棘手的。程序的调试构建通常使用调试crt(它启用堆检查和API断言等功能);生产dll,即使在调试中使用,也通常使用MSVCRT(生产线程安全版本)。我通过完全禁用调试crt、将所有构建设置为“多线程动态”来解决这个问题,因为维护单独的调试dll太麻烦了。这样做会失去一些调试功能。

退房:

void PySys_Set path(char*path)将sys.path设置为在path中找到的路径的列表对象,该对象应该是用平台的搜索路径分隔符(:在Unix上,;在Windows上)分隔的路径列表。

或者

Py_SetProgramName(argv[0]);将dirname(argv[0])添加到PYTHONPATH中。

我找到了跨平台解决方案。在调用任何其他python代码之前,只需执行以下python行:

import sys
sys.path.append("C:\\source\\\\modules")

相关问题 更多 >