【问题标题】:Python script to activate and keep open a Virtualenv用于激活并保持打开 Virtualenv 的 Python 脚本
【发布时间】:2017-09-05 13:44:10
【问题描述】:

我需要一个 python 脚本来激活 virtualenv,在 virtualenv 中运行另一个 python 程序,然后在第二个 python 程序关闭后关闭 virutalenv。这是我的代码:

import os
import subprocess
from subprocess import Popen

activate_dir = "C:/Users/JohnDoe/theprogram/Scripts/"
os.chdir(activate_dir)
subprocess.Popen(["activate.bat"])

cal_dir = "C:/Users/JohnDoe/theprogram/"
os.chdir(cal_dir)
os.system('python program_file.py')

但是,当此代码运行时,我从 program_file 收到导入错误,这意味着 virtualenv 未激活。我该如何解决这个问题?

谢谢

编辑: 这是在 Windows 环境中。

【问题讨论】:

  • 这个问题可能重复吗? stackoverflow.com/questions/6943208/…
  • 据我了解,链接的问题是关于使用 python 脚本专门激活 virtualenv。我的问题通过在激活 virtualenv 时更改目录并运行另一个 python 文件来补充。

标签: python python-3.x virtualenv


【解决方案1】:

我找到了一种在 Python 脚本中检测、激活和创建(如果需要)虚拟环境并在该虚拟环境中运行的方法,同时保留在该脚本中并且不使用从该脚本发出的 shell 命令(除了通过 pip list 显示已安装的包)。如果不使用 shell 命令,脚本将与操作系统无关。

这是一些示例代码。您只需从您使用的任何操作系统外壳(Windows、Linux、MacOS)运行它:

import os
import sys
import venv

def isvirtualenv():
    return sys.prefix != sys.base_prefix

def findfile(startdir, pattern):
    for root, dirs, files in os.walk(startdir):
        for name in files:
            if name.find(pattern) >= 0:
                return root + os.sep + name

    return None

venv_path = 'venv'            # This is an example path

if isvirtualenv():
    print('Already in virtual environment.')
else:
    if findfile(os.getcwd(), 'activate') is None:
        print('No virtual environment found. Creating one.')
        env = venv.EnvBuilder(with_pip = True)
        env.create(venv_path)
    else:
        print('Not in virtual environment. Virtual environment directory found.')

    # This is the heart of this script that puts you inside the virtual environment. 
    # There is no need to undo this. When this script ends, your original path will 
    # be restored.
    os.environ['PATH'] = os.path.dirname(findfile(os.getcwd(), 'activate')) + os.pathsep + os.environ['PATH']
    sys.path.insert(1, os.path.dirname(findfile(venv_path, 'easy_install.py')))

# Run your script inside the virtual environment from here
print(os.environ['PATH'])
os.system('pip list')

【讨论】:

  • 至少在我的系统(Windows 10)和我的虚拟环境中,最后一行不会指向虚拟环境中的site-packages(我认为这是意图),而是指向site-packages/setuptools/command。也许更好的选择是直接将findfile 用于setuptools 目录?
【解决方案2】:

问题是您正在使用该虚拟环境创建一个带有 subprocess.Popen(["activate.bat"]) 的新进程,您没有更改您的环境。您需要做的是在您跨越的同一进程中调用 python 脚本:

os.system("source activate;python -V")

或者您可以编写一个 shell 脚本来启动虚拟环境并调用您发送给它的任何 python 脚本。在 bash(在 linux 上)中,这将是:

#!/bin/bash
# start a virtual environment and call a python module
# usage: ./runVirenvPythonModule module.py
source activate
python $1 # this is the first cmd line argument passed in

【讨论】:

  • 啊,很好的答案!如果我使用os.system 命令,我将如何从我调用activateScripts 目录转到我调用python 脚本的program 目录?
  • 请注意 OP 代码中的 M$ Windows 样式路径。而且激活是通过批处理文件完成的。在 windows 中使用 bash 语法会很有趣。
猜你喜欢
  • 2020-01-16
  • 2011-10-20
  • 2018-08-02
  • 1970-01-01
  • 1970-01-01
  • 2020-09-06
  • 2017-12-18
  • 2018-05-05
相关资源
最近更新 更多