I make heavy use of virtualenv to isolate my development environments from the system-wide Python installation. Typical work-flow for using a virtualenv involves running
source /path/to/virtualenv/bin/activateto set the environment variables that Python requires to execute an isolated runtime. Making sure my Python executables use the current active virtualenv is as simple as setting the shebang to
#!/usr/bin/env python
Lately, though, I've been writing some C code that embeds the Python runtime. What I can't seem to figure out is how to get the embedded runtime to use t开发者_StackOverflow社区he current active virtualenv. Anybody got a good example to share?
Inspecting path and setting Py_SetProgramName worked for me:
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();
Seems to be not an answer, but still might be useful in other contexts.
Have you tried running bin/activate_this.py
from your Python virtualenv? The comment in this file of my virtualenv reads:
By using
execfile(this_file, dict(__file__=this_file))
you will activate this virtualenv environment.This can be used when you must use an existing Python interpreter, not the virtualenv
bin/python
You should achieve the desired result if you execute the runtime equivalent of the above code.
I found that @dikobraz's answer did not work for me on mac OSX venvs because even after setting PythonProgName
, the prefix and then PythonHome
were still incorrectly set to system python directories.
What worked for me instead was:
if (auto venv_path = std::getenv("VIRTUAL_ENV")) {
setenv("PYTHONHOME", venv_path, true);
}
before running Py_Initialize()
.
Well, the C API docs kind of imply it should just work (I read it as vaguely hinting the interpreter calls getenv itself), but seem to lack sufficient context to be certain, and I've never had occasion to actually test that.
Since it's apparently not working for you, what you're really looking for is probably going to be Py_SetPythonHome(char *home)
, which you should just need call with a copy of the string you get from getenv("PYTHONHOME")
.
You can, of course, also modify sys.path
for the effect of PYTHONPATH
, if needed.
From http://docs.python.org/release/1.5.2/api/embedding.html it seems that it will just work as long as your PATH has the virtualenv directory before the pre-installed python versions. If not, try setting PYTHONHOME as mentioned by Nicholas Knight.
You can the check the environment variable VIRTUAL_ENV to get the current envs location.
精彩评论