获取嵌入式Python运行时以使用当前活动的virtualenv

时间:2011-09-20 23:07:52

标签: python virtualenv

我大量使用virtualenv来将我的开发环境与系统范围的Python安装隔离开来。使用virtualenv的典型工作流程包括运行

source /path/to/virtualenv/bin/activate
来设置Python执行隔离运行时所需的环境变量。确保我的Python可执行文件使用当前活动的virtualenv就像将shebang设置为
#!/usr/bin/env python

一样简单

最近,我一直在编写一些嵌入Python运行时的C代码。我似乎无法弄清楚如何让嵌入式运行时使用当前活动的virtualenv。有人有一个很好的例子可以分享吗?

谢谢!

6 个答案:

答案 0 :(得分:4)

检查路径并设置Py_SetProgramName对我有用:

std::vector<std::string> paths;
std::string pathEnv = getenv("PATH");
boost::split(paths, pathEnv, boost::is_any_of(";:"));
for (std::string path : paths)
{
  boost::filesystem::path pythonPath = boost::filesystem::path(path) / "python";
  std::cout << pythonPath << std::endl;
  if (boost::filesystem::exists(pythonPath))
  {
    pythonProgramName_ = pythonPath.string(); // remember path, because Py_SetProgramName doesn't save it anywhere
    Py_SetProgramName(&pythonProgramName_[0]);
    break;
  }
}
Py_Initialize();

答案 1 :(得分:2)

  

似乎不是一个答案,但在其他情况下仍然有用。

您是否尝试过从Python virtualenv运行bin/activate_this.py?我的virtualenv的这个文件中的评论写道:

  

使用execfile(this_file, dict(__file__=this_file))即可   激活这个虚拟环境。

     

当您必须使用现有的Python解释器时,可以使用它   virtualenv bin/python

如果执行上述代码的运行时等效,则应该达到预期的结果。

答案 2 :(得分:1)

我发现@dikobraz的答案在mac OSX venvs上对我不起作用,因为即使在设置PythonProgName之后,前缀然后PythonHome仍然错误地设置为系统python目录。

对我有用的是:

if (auto venv_path = std::getenv("VIRTUAL_ENV")) {
    setenv("PYTHONHOME", venv_path, true);
}

在运行Py_Initialize()之前。

答案 3 :(得分:0)

嗯,C API docs暗示它应该起作用(我读它隐约暗示解释器称getenv本身),但似乎缺乏足够的背景来确定,我从来没有机会实际测试一下。

由于它显然不适合你,你真正想要的可能是Py_SetPythonHome(char *home),你应该只需要使用getenv("PYTHONHOME")获得的字符串副本来调用它。

当然,如果需要,您也可以修改sys.path PYTHONPATH的效果。

答案 4 :(得分:0)

http://docs.python.org/release/1.5.2/api/embedding.html开始,只要您的PATH在预安装的python版本之前具有virtualenv目录,它就会起作用。如果没有,请尝试按照Nicholas Knight的说法设置PYTHONHOME。

答案 5 :(得分:0)

您可以检查环境变量VIRTUAL_ENV以获取当前的envs位置。