使用 Python 脚本激活虚拟环境

2025-01-03 08:40:00
admin
原创
127
摘要:问题描述:我想从 Python 脚本激活虚拟环境实例。我知道这很容易做到,但我见过的所有例子都使用它在环境中运行命令,然后关闭子进程。我只是想激活虚拟环境并返回到 shell,就像 bin/activate 一样。像这样:$me: my-script.py -d env-name $(env-name)me:...

问题描述:

我想从 Python 脚本激活虚拟环境实例。

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

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

像这样:

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

这可能吗?

相关的:

virtualenv › 从脚本调用环境


解决方案 1:

如果您想在虚拟环境下运行 Python 子进程,您可以通过使用虚拟环境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 解释器而不是子进程下激活虚拟环境,您可以调用exec传递activate_this.py脚本,如下所示:

# Doing exec() 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"

exec(open(activate_this_file).read(), {'__file__': activate_this_file})

请注意,对于上述内容,您需要使用virtualenv库,而不是venv 。

如果您使用 venv,您可以复制 virtualenv 的 activate_this.py 的实现,只需进行一些小的改动,它就可以或多或少地与 venv 一起工作。

解决方案 2:

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

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

使脚本可执行:

chmod u+x script.py

运行脚本:

./script.py

瞧!

解决方案 3:

要根据官方Virtualenv 文档运行另一个 Python 环境,您可以在命令行中指定可执行 Python 二进制文件的完整路径,只需这样做(无需先激活虚拟环境):

/path/to/virtualenv/bin/python

如果您想使用虚拟环境从命令行调用脚本,同样适用。您无需先激活它:

me$ /path/to/virtualenv/bin/python myscript.py

对于 Windows 环境也一样(无论是从命令行还是从脚本):

> path    oenvScriptspython.exe myscript.py

解决方案 4:

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

首先,我必须创建一个 shell 脚本来包装“source”命令。也就是说,我使用了“.”,因为我读到过,对于 Bash 脚本来说,使用它比使用 source 更好。

#!/bin/bash
. /path/to/env/bin/activate

然后从我的 Python 脚本中我可以简单地执行以下操作:

import os
os.system('/bin/bash --rcfile /path/to/myscript.sh')

整个诡计就在于--rcfile争论之中。

当 Python 解释器退出时,它会将当前 shell 留在激活的环境中。

赢!

解决方案 5:

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

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

它基本上可以满足您的需要:

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

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

解决方案 6:

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

参考:Python 3 中 execfile 的替代品是什么?

解决方案 7:

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

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

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

解决方案 8:

我遇到了同样的问题,但在我的环境目录activate_this.py中没有。Scripts

激活这个.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

解决方案 9:

对于 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))

解决方案 10:

首先我来说一下我对这个问题的理解:

有没有办法可以运行一个命令,使某个虚拟环境(在多个虚拟环境之中)在我的交互式 shell 中变为活动状态?

简短的回答是:

没有 shell 的帮助就无法实现 —— 因为以正常方式编写的任何命令都将是一个子进程,并且无法直接修改 shell 中的设置。

也就是说,有办法从 shell 获得帮助,例如,假设有一个类似以下的脚本(伪代码):

#!/usr/bin/env python3

import sys

# writing this function is an exercise for the reader...
# I don't know what you're wanting to do here, but I'll
# assume you have some way to choose a venv directory
# based on command-line arguments:
env_dir = choose_env_dir_based_on(sys.ARGV)
print(f". #{env_dir}/bin/activate")

现在,假设(根据问题文本)您希望能够以这样的方式运行它my-script.py -d env-name(我可能会从中删除.py,但我会继续使用它,因为这就是问题的表述方式),让我们将其保存在一个名为的文件中~/bin/_my-script.py。从那里,您需要教您的 shell 如何以可以修改其自身环境的方式运行该命令。您可以通过几种不同的方式做到这一点。最简单的方法可能是使用别名:

alias my-script.py='eval `~/bin/_myscript.py`'

但是,这样做的缺点是,它没有很好的方法来获取参数,因此运行my-script.py -d env-name实际上不起作用(尽管如果您只需要运行my-script.py,那么就可以了)。相反,可以使用 shell 函数来完成:

my-script.py () { eval `~/bin/_my-script.py "$@"` }

无论您选择哪种方式,您大概都会将其保存在您正在使用的 shell 的、或任何等效文件~/.bashrc中。~/.zshrc

通过函数形式,我们可以输入 my-script.py -d env-name,同时让它实际执行以下操作:

  1. 运行~/bin/_my-script.py-d env-name作为参数提供)。

  2. 获取该脚本的输出eval(有关更多信息,请参阅此问答),以便它在您的 shell 上下文中运行。

  3. 由于_my-script.py实际要做的是打印出一个 shell 命令来获取相关目录的激活脚本,所以这就会发生。


奖励:自激活脚本:

因此,以上内容都回答了提出的问题。不过,我找到这个答案是为了寻找另一个问题的解决方案。我的问题可以总结如下:

我是否可以运行一个 Python 脚本,就好像它是在已经设置了特定 venv 的情况下运行的一样?

为此,可以运行类似下面的程序(我找到了自己的解决方案)。为了便于说明,我假设 venv 位于.env与正在运行的脚本一起存在的目录中。

#!/usr/bin/env python3

# the above "shebang" line references whatever python3
# we happen to have, whether or not an environment is set.

# But we want to run with the environment in .env relative
# to the current script, unless an env is activated (in
# which case, we'd use that, and do nothing special here):

import os, sys

if 'VIRTUAL_ENV' not in os.environ:
  # assuming .env is next to this script:
  venv = os.path.join(os.path.dirname(__file__), '.env')
  # finding the python from that env:
  newpython = os.path.join(venv, 'bin', 'python')
  # setting up a new ARGV, to start with the new python:
  args = [newpython] + sys.argv
  # Note: setting VIRTUAL_ENV isn't what causes the
  # virtualenv to be utilized.  Python has some other means
  # of doing that.  But it does signal to the if condition
  # above to not run this code more than once (lest we
  # go into an infinite execv loop).
  os.environ['VIRTUAL_ENV'] = venv
  # With that all set up, we re-run under the new python:
  os.execv(newpython, args)

import somemodule # something pip installed inside the venv.

# rest of code here

或者,对于强制 venv 所需的内容,给出一个简洁的版本:

#!/usr/bin/env python3

import os, sys
if 'VIRTUAL_ENV' not in os.environ:
  venv = os.path.join(os.path.dirname(__file__), '.env')
  newpython = os.path.join(venv, 'bin', 'python')
  args = [newpython] + sys.argv
  os.environ['VIRTUAL_ENV'] = venv
  os.execv(newpython, args)

(由于目录不存在而出现的“合理”错误消息.env留给读者作为练习。按原样,FileNotFoundError尝试运行时将引发错误os.execv。什么是“合理”大概取决于人们想要什么 - 自动创建 venv?只是报告错误?其他?因此将其留作练习。)

解决方案 11:

与此回复相关的是activate_this.py

如果这是您的用例(在同一进程上激活虚拟环境),您可能有兴趣使用activate-virtualenv,这是一个上下文管理器,它根据activate_this.py脚本自动激活和停用虚拟环境。

使用示例:

from activate_virtualenv import activate_virtualenv

venv_path = "/path/to/virtualenv"
with activate_virtualenv(venv_path):
    import subscript1

然后,将导入“ subscript1.py”,并激活虚拟环境。它将能够加载已激活虚拟环境上安装的任何模块。with块结束后,虚拟环境将自动停用,所做的更改activate_this.py将被撤消,因此不会影响脚本的其余部分。

解决方案 12:

您应该在一个文件夹中创建所有的virtualenvs,例如virt

假设你的虚拟环境文件夹名称是 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
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用