我想从 Python 脚本激活 virtualenv 实例。
我知道这很容易做到,但是我见过的所有示例都使用它在 env 中运行命令,然后关闭子进程。
我只是想激活 virtualenv 并返回到 shell,就像 bin/activate 一样。
像这样的东西:
$me: my-script.py -d env-name
$(env-name)me:
这可能吗?
相关的:
如果要在 virtualenv 下运行 Python 子进程,可以通过使用位于 virtualenv 的 /bin/ 目录中的 Python 解释器运行脚本来实现:
import subprocess
# Path to a Python interpreter that runs any Python script
# under the virtualenv /path/to/virtualenv/
python_bin = "/path/to/virtualenv/bin/python"
# Path to the script that must run under the virtualenv
script_file = "must/run/under/virtualenv/script.py"
subprocess.Popen([python_bin, script_file])
但是,如果您想在当前 Python 解释器而不是子进程下激活 virtualenv,您可以使用 activate_this.py
脚本:
# Doing execfile() on this file will alter the current interpreter's
# environment so you can import libraries in the virtualenv
activate_this_file = "/path/to/virtualenv/bin/activate_this.py"
execfile(activate_this_file, dict(__file__=activate_this_file))
在 virtualenv 的解释器下运行脚本的最简单的解决方案是将默认的 shebang 行替换为 virtualenv 的解释器的路径,就像在脚本开头那样:
#!/path/to/project/venv/bin/python
使脚本可执行:
chmod u+x script.py
运行脚本:
./script.py
瞧!
事实证明,是的,问题并不简单,但解决方案却很简单。
首先,我必须创建一个 shell 脚本来包装“源”命令。那就是说我用了“。”相反,因为我读过它比使用 Bash 脚本的源代码更好。
#!/bin/bash
. /path/to/env/bin/activate
然后从我的 Python 脚本中,我可以简单地做到这一点:
import os
os.system('/bin/bash --rcfile /path/to/myscript.sh')
整个技巧在于 --rcfile
参数。
当 Python 解释器退出时,它会将当前 shell 留在激活的环境中。
赢!
os.system('/bin/bash --rcfile path/to/env/activate')
您知道,当启动 bash 实例时,它会将 .bashrc 作为 --rcfile 的参数。所以只需指定 rcfile 是您的激活文件...不是吗?
cat ~/.bashrc env/bin/activate > env/bin/activate2 && /bin/bash --rcfile env/bin/activate2
要按照官方的Virtualenv documentation运行另一个 Python 环境,在命令行中你可以指定可执行 Python 二进制文件的完整路径,就是这样(之前不需要激活 virtualenv):
/path/to/virtualenv/bin/python
如果您想使用 virtualenv 从命令行调用脚本,这同样适用。您不需要在此之前激活它:
me$ /path/to/virtualenv/bin/python myscript.py
对于 Windows 环境也是如此(无论是来自命令行还是来自脚本):
> \path\to\env\Scripts\python.exe myscript.py
只是一个对我有用的简单解决方案。我不知道您为什么需要基本上执行无用步骤的 Bash 脚本(我错了吗?)
import os
os.system('/bin/bash --rcfile flask/bin/activate')
这基本上可以满足您的需求:
[hellsing@silence Foundation]$ python2.7 pythonvenv.py
(flask)[hellsing@silence Foundation]$
然后不用停用虚拟环境,只需 Ctrl + D 或退出。这是一个可能的解决方案还是不是你想要的?
最佳答案仅适用于 Python 2.x
对于 Python 3.x,请使用:
activate_this_file = "/path/to/virtualenv/bin/activate_this.py"
exec(compile(open(activate_this_file, "rb").read(), activate_this_file, 'exec'), dict(__file__=activate_this_file))
参考:What is an alternative to execfile in Python 3?
子进程环境在它不复存在的那一刻就丢失了,将环境内容从那里移动到父进程有点棘手。
您可能需要生成一个 shell 脚本(您可以动态生成一个到 /tmp),它将把 virtualenv 环境变量输出到一个文件中,然后您可以在父 Python 进程中读取该文件并放入 os.environ。
或者您只需解析激活脚本中使用的 open("bin/activate") 中的行,手动提取内容,然后放入 os.environ。这很棘手,但并非不可能。
对于 python2/3,使用下面的代码片段我们可以激活虚拟环境。
activate_this = "/home/<--path-->/<--virtual env name -->/bin/activate_this.py" #for ubuntu
activate_this = "D:\<-- path -->\<--virtual env name -->\Scripts\\activate_this.py" #for windows
with open(activate_this) as f:
code = compile(f.read(), activate_this, 'exec')
exec(code, dict(__file__=activate_this))
platform.system()
我们在哪个操作系统中,然后将 activate_this
设置为它需要的值?
我遇到了同样的问题,我的环境的 Scripts
目录中没有 activate_this.py
。
激活这个.py
"""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
"""
try:
__file__
except NameError:
raise AssertionError(
"You must run this like execfile('path/to/active_this.py', dict(__file__='path/to/activate_this.py'))")
import sys
import os
base = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
if(sys.platform=='win32'):
site_packages = os.path.join(base, 'Lib', 'site-packages')
else:
site_packages = os.path.join(base, 'lib', 'python%s' % sys.version[:3], 'site-packages')
prev_sys_path = list(sys.path)
import site
site.addsitedir(site_packages)
sys.real_prefix = sys.prefix
sys.prefix = base
# Move the added items to the front of the path:
new_sys_path = []
for item in list(sys.path):
if item not in prev_sys_path:
new_sys_path.append(item)
sys.path.remove(item)
sys.path[:0] = new_sys_path
将该文件复制到您环境的 Scripts
目录中,然后像这样使用它:
def activate_virtual_environment(environment_root):
"""Configures the virtual environment starting at ``environment_root``."""
activate_script = os.path.join(
environment_root, 'Scripts', 'activate_this.py')
execfile(activate_script, {'__file__': activate_script})
activate_virtual_environment('path/to/your/venv')
参考:https://github.com/dcreager/virtualenv/blob/master/virtualenv_support/activate_this.py
您应该在一个文件夹中创建所有 virtualenv
,例如 virt
。
假设您的 virtualenv 文件夹名称是 virt,如果不更改它
cd
mkdir custom
复制以下行...
#!/usr/bin/env bash
ENV_PATH="$HOME/virt/$1/bin/activate"
bash --rcfile $ENV_PATH -i
创建一个shell脚本文件并粘贴上面的行...
touch custom/vhelper
nano custom/vhelper
为您的文件授予可执行权限:
sudo chmod +x custom/vhelper
现在导出该自定义文件夹路径,以便您可以通过单击选项卡在命令行中找到它...
导出 PATH=$PATH:"$HOME/custom"
现在您只需键入以下命令即可在任何地方使用它...
vhelper YOUR_VIRTUAL_ENV_FOLDER_NAME
假设它是 abc 那么...
vhelper abc
subprocess.Popen([venv_python_file, script_file])
吗?script_file
,还是必须在virtualenv
目录中?script_file
不必在 virtualenv 目录中,它可以在任何地方。exec(compile(open(activate_this_file, "rb").read(), activate_this_file, 'exec'), dict(__file__=activate_this_file))