运行脚本时自动加载virtualenv

时间:2014-05-15 13:00:44

标签: python virtualenv

我有一个需要来自virtualenv的依赖项的python脚本。我想知道是否有某种方法可以将它添加到我的路径并让它自动启动它的virtualenv,运行然后回到系统的python。

我尝试使用autoenv和.env,但这似乎并没有完全符合我的要求。我还想过改变shabang指向virtualenv路径,但这似乎很脆弱。

7 个答案:

答案 0 :(得分:19)

有两种方法可以做到这一点:

  1. 将虚拟环境python的名称放入脚本的第一行。喜欢这个

    #!/你/虚拟/ ENV /路/斌/ Python的

  2. 将虚拟环境目录添加到sys.path。请注意,您需要导入sys库。喜欢这个

    导入sys

    sys.path.append( '/路径/到/虚拟/ env的/ lib中')

  3. 如果使用第二个选项,则可能需要向sys.path(站点等)添加多个路径。获得它的最好方法是运行你的虚拟env python解释器并删除sys.path值。像这样:

    /your/virtual/env/bin/python
    
    Python blah blah blah
    
    > import sys
    > print sys.path
    [ 'blah', 'blah' , 'blah' ]
    

    将sys.path的值复制到上面的代码段中。

答案 1 :(得分:11)

我很惊讶没有人提到这一点,但这就是为什么在virtualenv的bin目录中有一个名为activate_this.py的文件。您可以将其传递给execfile()以更改当前运行的解释器的模块搜索路径。

# 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中运行。与修改hashbang不同,您可以使用相对路径:

script_directory = os.path.dirname(os.path.abspath(__file__))
activate_this_file = os.path.join(script_directory, '../../relative/path/to/env/bin/activate_this.py')

答案 2 :(得分:5)

来自virtualenv documentation

  

如果直接从中运行脚本或python解释器   virtualenv的bin /目录(例如path / to / env / bin / pip或   / path / to / env / bin / python script.py)不需要激活。

因此,如果您只是在virtualenv中调用python可执行文件,那么您的virtualenv将是“活动的”。所以你可以创建一个这样的脚本:

#!/bin/bash

PATH_TO_MY_VENV=/opt/django/ev_scraper/venv/bin

$PATH_TO_MY_VENV/python -c 'import sys; print(sys.version_info)'
python -c 'import sys; print(sys.version_info)'

当我在我的系统上运行这个脚本时,两个调用python打印出你在下面看到的内容。 (Python 3.2.3在我的virtualenv中,2.7.3是我的系统Python。)

sys.version_info(major=3, minor=2, micro=3, releaselevel='final', serial=0)
sys.version_info(major=2, minor=7, micro=3, releaselevel='final', serial=0)

因此,当您致电$PATH_TO_MY_VENV/python时,您在virtualenv中安装的所有库都将可用。对普通系统python的调用当然不会发现virtualenv中的任何内容。

答案 3 :(得分:3)

我认为这里最好的答案是创建一个简单的脚本并将其安装在virtualenv中。然后,您可以直接使用该脚本,也可以创建符号链接等等。

以下是一个例子:

$ mkdir my-tool
$ cd my-tool
$ mkdir scripts
$ touch setup.py
$ mkdir scripts
$ touch scripts/crunchy-frog
$ chmod +x scripts/crunchy-frog

<强>松脆蛙

#!/usr/bin/env python
print("Constable Parrot ate one of those!")

<强> setup.py

from setuptools import setup

setup(name="my-cool-tool",
      scripts=['scripts/crunchy-frog'],
      )

现在:

$ source /path/to/my/env/bin/activate
(env) $ python setup.py develop 
(env) $ deactivate
$ cd ~
$ ln -s /path/to/my/env/bin/crunchy-frog crunchy-frog
$ ./crunchy-frog
Constable Parrot ate one of those!

当您安装脚本时(通过setup.py installsetup.py develop),它将用{b}线替换scripts的第一行用于env python(您可以使用$ head /path/to/my/env/bin/crunchy-frog)。因此,无论何时运行该特定脚本,它都将使用该特定的Python环境。

答案 4 :(得分:0)

这有帮助吗?

import site
site.addsitedir('/path/to/virtualenv/lib/python2.7/site-packages/')

答案 5 :(得分:0)

之前我遇到过这个问题,我做了一个简单的脚本来递归地查找virtualenv文件夹,只是导入和调用一个函数:

<强> script_autoenv.py

# -*- coding:utf-8 -*- 
import os, site

def locate_env(path, env_name):
    """search for a env directory name in each directory in the path"""
    if os.path.isdir(path + "/env"):
        env_26_path = '%s/%s/lib/python2.6/site-packages/' % (path, env_name)
        env_27_path = '%s/%s/lib/python2.7/site-packages/' % (path, env_name)


        if os.path.isdir(env_26_path):
            site.addsitedir(env_26_path)
            print "Virtualenv 2.6 founding"
        elif os.path.isdir(env_27_path):
            site.addsitedir(env_27_path)
            print "Virtualenv 2.7 founding"
    else:
        new_path, old_dir = os.path.split(path)
        if old_dir:
            locate_env(new_path, env_name)
        else:
            print "No envs found"

您只需指定脚本目录和env名称文件夹,脚本执行其余操作:

<强> test.py

# -*- coding:utf-8 -*-

import os
import script_autoenv
script_autoenv.locate_env(os.path.realpath(__file__), 'env')

import django
print django.VERSION

我希望它适合你

答案 6 :(得分:0)

答案可能是00:00:00https://pipenv.readthedocs.io/en/latest/)。

  • 它将允许您执行以下操作:
df.groupby(['sourcehostname','destinationaddress'])['tvalue'].diff().fillna(0)

使用指定的库在python环境中运行#Create delta df['delta'] = df.groupby(['sourcehostname','destinationaddress'])(df['tvalue']-df['tvalue'].shift()).fillna(0)

...也许并非您要找的东西,但是在重新发明它之前值得一看。