ChatGPT解决这个技术问题 Extra ChatGPT

使用 Python 脚本激活 virtualenv

我想从 Python 脚本激活 virtualenv 实例。

我知道这很容易做到,但是我见过的所有示例都使用它在 env 中运行命令,然后关闭子进程。

我只是想激活 virtualenv 并返回到 shell,就像 bin/activate 一样。

像这样的东西:

$me: my-script.py -d env-name
$(env-name)me:

这可能吗?

相关的:

virtualenv › Invoking an env from a script


J
Jean-François Fabre

如果要在 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))

// , 这个答案的第一个代码块中的最后一行不应该如下所示:subprocess.Popen([venv_python_file, script_file]) 吗?
// , 另外,有没有办法从任意位置运行 script_file,还是必须在 virtualenv 目录中?
已修复,感谢您注意到错误。至于你的第二个问题,没有 script_file 不必在 virtualenv 目录中,它可以在任何地方。
你如何使用第二个选项和 python3 来做到这一点?看起来 exec 已经替换了 python3 中的 execfile,但我无法让它工作。
@djsosofresh 这显然在 Python 3.6 中对我有用:exec(compile(open(activate_this_file, "rb").read(), activate_this_file, 'exec'), dict(__file__=activate_this_file))
P
Peter Mortensen

在 virtualenv 的解释器下运行脚本的最简单的解决方案是将默认的 shebang 行替换为 virtualenv 的解释器的路径,就像在脚本开头那样:

#!/path/to/project/venv/bin/python

使脚本可执行:

chmod u+x script.py

运行脚本:

./script.py

瞧!


+1 优雅。在 Windows 上请注意,这需要一个兼容 posix 的环境,该环境可以理解 shebang 行,如 cygwin 或 msys
适用于 python 3.6.3 和 windows 10!
想我可能误解了原来的问题。他想用脚本激活虚拟环境,并带着激活的环境返回shell。我的答案在虚拟环境中运行脚本,但返回的 shell 不保留环境。现代解决方案是 virtualenvwrapper:virtualenvwrapper.readthedocs.io/en/latest/#。它允许一个人在不同的 virtualenvs 之间激活和切换。
这就像魔术一样!
P
Peter Mortensen

事实证明,是的,问题并不简单,但解决方案却很简单。

首先,我必须创建一个 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 是您的激活文件...不是吗?
@Depado我刚刚尝试了您的解决方案,这将激活python中的shell。至少当我在 shell 中尝试时。 >>> os.system('/bin/bash --rcfile /var/envs/test/bin/activate') (test)tcraig@tallis-desktop:~$ (test)tcraig@tallis-desktop:~$ ls -l 总计 706288
也许可以,但这在脚本中有效。这种技术的唯一不便之处是您无法获得所有别名以及您在 ~/.bashrc 中的所有内容。但我很好。例如,“ls”命令没有颜色。但一切都对我有用。当我想离开时,我只需 Ctrl+D
“当 python 解释器退出时,它会将当前 shell 留在激活的环境中”什么?它生成一个全新的 shell 作为子进程并等待它完成。
为了避免在我的存储库上创建更多新文件并复制当前的 bash 配置,我这样做了:cat ~/.bashrc env/bin/activate > env/bin/activate2 && /bin/bash --rcfile env/bin/activate2
M
Mariano Ruiz

要按照官方的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

问题是:使用 python 脚本激活 virtualenv(不是来自 Shell)
是的,我的观点是,您可以从虚拟环境中调用 python 运行时,而无需事先从控制台或脚本中激活它。我会澄清答案,谢谢!
哦,我的天啊!我没有考虑。这是唯一对我有用的解决方案:)。现在,当我从 php 执行 python 脚本时,我正在使用:“path/to/virtualenv/bin/python mypythonscript.py”
P
Peter Mortensen

只是一个对我有用的简单解决方案。我不知道您为什么需要基本上执行无用步骤的 Bash 脚本(我错了吗?)

import os
os.system('/bin/bash  --rcfile flask/bin/activate')

这基本上可以满足您的需求:

[hellsing@silence Foundation]$ python2.7 pythonvenv.py
(flask)[hellsing@silence Foundation]$

然后不用停用虚拟环境,只需 Ctrl + D 或退出。这是一个可能的解决方案还是不是你想要的?


P
Peter Mortensen

最佳答案仅适用于 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?


什么是activate_this.py
@randyPen,在项目目录中构建 virtualenv 时会自动添加 activate_this.py 文件。 (即/project/directory/venv/bin/activate_this.py)
请注意,Python 不会在所有操作系统上使用相同的 dir 结构,因此这不是一个通用的解决方案(其他问题也不是,但如果将其更新为“just work(tm)”就好了不在任何 Windows 机器上工作)
P
Peter Mortensen

子进程环境在它不复存在的那一刻就丢失了,将环境内容从那里移动到父进程有点棘手。

您可能需要生成一个 shell 脚本(您可以动态生成一个到 /tmp),它将把 virtualenv 环境变量输出到一个文件中,然后您可以在父 Python 进程中读取该文件并放入 os.environ。

或者您只需解析激活脚本中使用的 open("bin/activate") 中的行,手动提取内容,然后放入 os.environ。这很棘手,但并非不可能。


R
Ronak Delvadiya

对于 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 设置为它需要的值?
r
rahul_5409

我遇到了同样的问题,我的环境的 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


P
Peter Mortensen

您应该在一个文件夹中创建所有 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