web-dev-qa-db-fra.com

Déterminer si Python est exécuté dans virtualenv

Est-il possible de déterminer si le script en cours est exécuté dans un environnement virtualenv?

192
miracle2k

D'après les informations dont je dispose, le moyen le plus fiable de vérifier cela (et la manière utilisée en interne dans virtualenv et dans pip) consiste à vérifier l'existence de sys.real_prefix:

import sys

if hasattr(sys, 'real_prefix'):
    #...

Dans virtualenv, sys.prefix pointe vers le répertoire virtualenv, et sys.real_prefix désigne le préfixe "réel" du système Python (souvent /usr ou /usr/local ou quelque chose du genre).

En dehors d'un virtualenv, sys.real_prefix ne devrait pas exister.

L'utilisation de la variable d'environnement VIRTUAL_ENV n'est pas fiable. Il est défini par le script shell virtualenv activate, mais virtualenv peut être utilisé sans activation en exécutant directement un fichier exécutable à partir du répertoire bin/ (ou Scripts) de virtualenv, auquel cas $VIRTUAL_ENV ne sera pas défini.

189
Carl Meyer

Essayez d'utiliser pip -V (notice majuscule V)

Si vous utilisez l'environnement virtuel. cela montrera le chemin d'accès à l'emplacement de l'env.

54
loki l

Ceci est une amélioration de la réponse acceptée par Carl Meyer . Cela fonctionne avec virtualenv pour Python 3 et 2 ainsi que pour le module venv dans Python 3:

import sys


def is_venv():
    return (hasattr(sys, 'real_prefix') or
            (hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix))

Le contrôle de sys.real_prefix couvre virtualenv, l’égalité de sys.base_prefix non vide avec sys.prefix couvre venv.

Considérons un script qui utilise la fonction comme ceci:

if is_venv():
    print('inside virtualenv or venv')
else:
    print('outside virtualenv or venv')

Et l'invocation suivante:

$ python2 test.py 
outside virtualenv or venv

$ python3 test.py 
outside virtualenv or venv

$ python2 -m virtualenv virtualenv2
...
$ . virtualenv2/bin/activate
(virtualenv2) $ python test.py 
inside virtualenv or venv
(virtualenv2) $ deactivate

$ python3 -m virtualenv virtualenv3
...
$ . virtualenv3/bin/activate
(virtualenv3) $ python test.py 
inside virtualenv or venv
(virtualenv3) $ deactivate 

$ python3 -m venv venv3
$ . venv3/bin/activate
(venv3) $ python test.py 
inside virtualenv or venv
(venv3) $ deactivate 
41
hroncok

L'utilisation de la variable $ VIRTUAL_ENV vérifiera si nous nous trouvons dans un environnement virtuel, mais le problème pourrait être avec la fonction de désactivation qui n'efface pas cette variable lorsque nous quittons virtualenv.

24
MrHetii

Selon virtualenv pep à http://www.python.org/dev/peps/pep-0405/#specification vous pouvez simplement utiliser sys.prefix à la place de os.environ ['VIRTUAL_ENV'].

le préfixe sys.real n'existe pas dans mon virtualenv et de même avec le préfixe sys.base.

17
chronossc

J'utilise régulièrement plusieurs environnements virtuels installés par Anaconda (venv). Cet extrait de code/exemples vous permet de déterminer si vous êtes ou non dans un environnement virtuel (ou de votre environnement système) et de demander également un élément graphique spécifique pour votre script.

AJOUTER AU PYTHON SCRIPT (extrait de code):

# ----------------------------------------------------------------------------
# Want script to run in Python 3.5 (has required installed OpenCV, imutils, ... packages):
import os

# First, see if we are in a conda venv { py27: Python 2.7 | py35: Python 3.5 | tf: TensorFlow | thee : Theano }
try:
   os.environ["CONDA_DEFAULT_ENV"]
except KeyError:
   print("\tPlease set the py35 { p3 | Python 3.5 } environment!\n")
   exit()

# If we are in a conda venv, require the p3 venv:
if os.environ['CONDA_DEFAULT_ENV'] != "py35":
    print("\tPlease set the py35 { p3 | Python 3.5 } environment!\n")
    exit()

# See also:
# Python: Determine if running inside virtualenv
# http://stackoverflow.com/questions/1871549/python-determine-if-running-inside-virtualenv  
# [ ... SNIP! ... ]

LANCEZ VOTRE SCRIPT (exemples):

$ python  webcam_cv3_v2_fps_v2c.py  -n50
    Please set the py35 { p3 | Python 3.5 } environment!

$ thee
  [Theano in Anaconda Python 2.7 venv (source activate theano-env)]

(theano-env) $ python  webcam_cv3_v2_fps_v2c.py  -n50
    Please set the py35 { p3 | Python 3.5 } environment!

(theano-env) $ tf
  [TensorFlow in Anaconda Python 2.7 venv (source activate tf-env]

(tf-env) $ python  webcam_cv3_v2_fps_v2c.py  -n50
    Please set the py35 { p3 | Python 3.5 } environment!

(tf-env) $ p2
  [Anaconda Python 2.7 venv (source activate py27)]

(py27) $ python  webcam_cv3_v2_fps_v2c.py  -n50
    Please set the py35 { p3 | Python 3.5 } environment!

(py27) $ p3
  [Anaconda Python 3.5 venv (source activate py35)]

(py35) $ python  webcam_cv3_v2_fps_v2c.py  -n50

    current env: py35
    processing (live): found 2 faces and 4 eyes in this frame

    threaded OpenCV implementation
    num_frames: 50
    webcam -- approx. FPS: 18.59
    Found 2 faces and 4 eyes!

(py35) $ sd
  [Anaconda venv deactivate (source deactivate)]

$ python  webcam_cv3_v2_fps_v2c.py  -n50
    Please set the py35 { p3 | Python 3.5 } environment!

$ ## Q.E.D.  ;-)

Mise à jour: utilisation dans les scripts bash:

Vous pouvez également utiliser cette approche dans les scripts bash (par exemple, ceux qui doivent être exécutés dans un environnement virtuel spécifique). Exemple (ajouté au script bash):

# ----------------------------------------------------------------------------
# Excerpt from: /mnt/Vancouver/Programming/scripts/tf_tb_del.sh      ## tf_tb_del: tf_tensorboard_delete
# [bash script run on command-line: calls TensorFlow-related commands, therefore must be run in tf-env venv]

if [ $CONDA_DEFAULT_ENV ]        ## << note the spaces (important in bash)!
then
    printf  '\n\tvenv: tf-env\n'
else
    printf '\n\n\t*******************************************************************\n'
    printf '\t***  NOTE! Must run this script in tf-env virtual environment!  ***\n'
    printf '\t*******************************************************************'
    exit
fi
## [ ... snip ... ]
3
Victoria Stuart

Pour vérifier si vous êtes à l'intérieur de Virtualenv:

import os

if os.getenv('VIRTUAL_ENV'):
    print('Using Virtualenv')
else:
    print('Not using Virtualenv')

Vous pouvez également obtenir plus de données sur votre environnement:

import sys
import os

print(f'Python Executable: {sys.executable}')
print(f'Python Version: {sys.version}')
print(f'Virtualenv: {os.getenv("VIRTUAL_ENV")}')
2
Matt Harasymczuk

(édité) J'ai trouvé ça ainsi, qu'en penses-tu? (Il retourne également le chemin de base venv et fonctionne même pour readthedocs là où la vérification de la variable env ​​ne fonctionne pas)

import os
import sys
from distutils.sysconfig import get_config_vars


def get_venv_basedir():
    """Returns the base directory of the virtualenv, useful to read configuration and plugins"""

    exec_prefix = get_config_vars()['exec_prefix']

    if hasattr(sys, 'real_prefix') is False or exec_prefix.startswith(sys.real_prefix):
        raise EnvironmentError('You must be in a virtual environment')

    return os.path.abspath(get_config_vars()['exec_prefix'] + '/../')
1
user8314429

C'est une vieille question, mais trop d'exemples ci-dessus sont trop compliqués.

Keep It Simple: (dans Jupyter Notebook ou Python 3.7.1 sur Windows 10)


import sys
print(sys.executable)```

# example output: >> `C:\Anaconda3\envs\quantecon\python.exe`

OR 
```sys.base_prefix```

# Example output: >> 'C:\\Anaconda3\\envs\\quantecon'
0

Vous pouvez faire which python et voir s’il pointe vers celui de virtual env. 

0
kunrazor

Il y a déjà beaucoup de bonnes méthodes publiées ici, mais juste en ajouter une de plus:

import site
site.getsitepackages()

vous indique où pip a installé les packages.

0
flow2k

Ce n'est pas pareil, mais pour les environnements UNIX, un test simple comme

if run("which python3").find("venv") == -1:
    # something when not executed from venv

fonctionne très bien pour moi. Il est plus simple de tester les attributs existants et, de toute façon, vous devriez nommer votre répertoire venv venv.

0
Libor Jelinek

Dans Windows OS, vous voyez quelque chose comme ceci: 

C:\Users\yourusername\virtualEnvName\Scripts>activate
(virtualEnvName) C:\Users\yourusername\virtualEnvName\Scripts>

Les parenthèses signifient que vous êtes réellement dans l'environnement virtuel appelé "virtualEnvName".

0
getleft

Une solution potentielle est:

os.access(sys.executable, os.W_OK)

Dans mon cas, je voulais simplement savoir si je pouvais installer des éléments avec pip tels quels. Bien que cela puisse ne pas être la bonne solution pour tous les cas, envisagez simplement de vérifier si vous disposez d'autorisations en écriture pour l'emplacement de l'exécutable Python.

Remarque: cela fonctionne dans toutes les versions de Python, mais renvoie également True si vous exécutez le système Python avec Sudo. Voici un cas d'utilisation potentiel:

import os, sys
can_install_pip_packages = os.access(sys.executable, os.W_OK)

if can_install_pip_packages:
    import pip
    pip.main(['install', 'mypackage'])

Le moyen le plus simple est simplement de lancer: which python, si vous êtes dans un environnement virtuel, il pointe sur son python au lieu de l’ordre global.

0
Silvio Biasiol