Est-il possible de déterminer si le script actuel s'exécute dans un environnement virtualenv?
Est-il possible de déterminer si le script actuel s'exécute dans un environnement virtualenv?
Réponses:
AFAIK le moyen le plus fiable de vérifier cela (et la manière qui est utilisée en interne dans virtualenv et dans pip) est de vérifier l'existence de sys.real_prefix
:
import sys
if hasattr(sys, 'real_prefix'):
#...
À l'intérieur d'un virtualenv, sys.prefix
pointe vers le répertoire virtualenv et sys.real_prefix
pointe vers le "vrai" préfixe du système Python (souvent /usr
ou/usr/local
ou quelque).
En dehors d'un virtualenv, sys.real_prefix
ne devrait pas exister.
L'utilisation de la VIRTUAL_ENV
variable d'environnement n'est pas fiable. Il est défini par le activate
script shell virtualenv , mais un virtualenv peut être utilisé sans activation en exécutant directement un exécutable à partir du répertoire virtualenv bin/
(ou Scripts
), auquel cas $VIRTUAL_ENV
il ne sera pas défini.
PYTHON_ENV=$(python -c "import sys; sys.stdout.write('1') if hasattr(sys, 'real_prefix') else sys.stdout.write('0')")
Essayez d'utiliser pip -V
(notez la majuscule V)
Si vous exécutez l'environnement virtuel. il montrera le chemin vers l'emplacement de l'env.
virtualenv
, il est possible que cela vous échoue ou vous mente. S'il ment, vous pouvez le faire find /path/to/venv/ -type f -exec sed -ie "s:/old/path/to/venv:/path/to/venv:g" {} \+
. Si cela échoue (j'ai "de mauvaises données de marshal"), vous devrez effacer les fichiers .pyc avec find /path/to/venv -type f -name "*.pyc" -exec rm {} \+
(ne vous inquiétez pas, ils se reconstruiront automatiquement).
...\lib\site-packages
dans le %PATH%
. Il retournera donc un faux positif dans ce cas.
Il s'agit d'une amélioration de la réponse acceptée par Carl Meyer . Il fonctionne avec virtualenv pour Python 3 et 2 et également 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))
La vérification des sys.real_prefix
couvertures virtualenv, l'égalité des non-vides sys.base_prefix
avec les sys.prefix
couvertures venv.
Considérez 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
def is_venv(): return hasattr(sys, 'real_prefix') or sys.base_prefix != sys.prefix
. Je dis juste.
pipenv
les environnements virtuels créés.
Vérifiez la $VIRTUAL_ENV
variable d'environnement.
La $VIRTUAL_ENV
variable d'environnement contient le répertoire de l'environnement virtuel dans un environnement virtuel actif.
>>> import os
>>> os.environ['VIRTUAL_ENV']
'/some/path/project/venv'
Une fois que vous exécutez deactivate
/ quittez l'environnement virtuel, la $VIRTUAL_ENV
variable sera effacée / vide. Python lèvera un KeyError
car la variable d'environnement n'a pas été définie.
>>> import os
>>> os.environ['VIRTUAL_ENV']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/os.py", line 678, in __getitem__
raise KeyError(key) from None
KeyError: 'VIRTUAL_ENV'
Ces mêmes vérifications de variables d'environnement peuvent bien sûr également être effectuées en dehors du script Python, dans le shell.
virtualenv
virtualenv et un venv
virtualenv.
Selon le pep virtualenv sur http://www.python.org/dev/peps/pep-0405/#specification, vous pouvez simplement utiliser sys.prefix à la place os.environ ['VIRTUAL_ENV'].
le sys.real_prefix n'existe pas dans mon virtualenv et pareil avec sys.base_prefix.
sys.real_prefix
.
env |grep VIRTUAL_ENV |wc -l
qui retournera un 1 si dans un venv ou un 0 sinon.
[[ -n $VIRTUAL_ENV ]] && echo virtualenv
ou [[ -z $VIRTUAL_ENV ]] && echo not virtualenv
selon vos besoins.
Pour vérifier si votre Virtualenv intérieur:
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")}')
Il y a plusieurs bonnes réponses ici, et certaines moins robustes. Voici un aperçu.
Ne vous fiez pas à l'emplacement de Python ou site-packages
dossier.
Si ceux-ci sont définis sur des emplacements non standard, cela ne signifie pas que vous êtes réellement dans un environnement virtuel. Les utilisateurs peuvent avoir plus d'une version Python installée, et ce n'est pas toujours là où vous vous attendez.
Évitez de regarder:
sys.executable
sys.prefix
pip -V
which python
En outre, ne vérifie pas la présence de venv
, .venv
ou envs
dans l' un de ces chemins. Cela se cassera pour les environnements avec un emplacement plus unique. Par exemple,
Pipenv utilise des valeurs de hachage comme nom pour ses environnements.
VIRTUAL_ENV
variable d'environnementLes deux virtualenv
et venv
définissent la variable d'environnement $VIRTUAL_ENV
lors de l'activation d'un environnement. Voir PEP 405 .
Vous pouvez lire cette variable dans des scripts shell ou utiliser ce code Python pour déterminer si elle est définie.
import os
running_in_virtualenv = "VIRTUAL_ENV" in os.environ
# alternative ways to write this, also supporting the case where
# the variable is set but contains an empty string to indicate
# 'not in a virtual environment':
running_in_virtualenv = bool(os.environ.get("VIRTUAL_ENV"))
running_in_virtualenv = bool(os.getenv("VIRTUAL_ENV"))
Le problème est que cela ne fonctionne que lorsque l'environnement est activé par le activate
script shell.
Vous pouvez démarrer les scripts de l'environnement sans activer l'environnement , donc si c'est un problème, vous devez utiliser une méthode différente.
sys.base_prefix
virtualenv
, venv
Et le pyvenv
point sys.prefix
à Python installé à l' intérieur de l'virtualenv que vous attendez.
Dans le même temps, la valeur d' origine de sys.prefix
est également disponible en tant que sys.base_prefix
.
Nous pouvons l'utiliser pour détecter si nous sommes dans un virtualenv.
import sys
# note: Python versions before 3.3 don't have sys.base_prefix
# if you're not in virtual environment
running_in_virtualenv = sys.prefix != sys.base_prefix
sys.real_prefix
Attention maintenant, virtualenv
avant que la version 20 ne soit pas définie, sys.base_prefix
mais elle est définie à la sys.real_prefix
place.
Donc, pour être sûr, vérifiez les deux comme suggéré dans la réponse de hroncok :
import sys
real_prefix = getattr(sys, "real_prefix", None)
base_prefix = getattr(sys, "base_prefix", sys.prefix)
running_in_virtualenv = (base_prefix or real_prefix) != sys.prefix
Si vous utilisez des environnements virtuels Anaconda, vérifiez la réponse de Victoria Stuart .
running_in_virtualenv = sys.*base_*prefix != sys.prefix
if hasattr(sys, 'real_prefix'):
test, qui ne fonctionnait plus.
Vous pouvez faire which python
et voir si son pointage vers celui dans env virtuel.
which
n'est pas disponible par défaut sous Windows. Vous pouvez utiliser à la where
place sur Windows ou utiliser quel artisanat . Ou regardez sys.executable
. Mais encore, il existe de meilleures méthodes.
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 venv (ou votre environnement système), et d'exiger également un venv spécifique pour votre script.
Ajouter au script Python (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! ... ]
Exemple:
$ p2
[Anaconda Python 2.7 venv (source activate py27)]
(py27) $ python webcam_.py
Please set the py35 { p3 | Python 3.5 } environment!
(py27) $ p3
[Anaconda Python 3.5 venv (source activate py35)]
(py35) $ python webcam.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) $
Mise à jour 1 - utilisation dans les scripts bash:
Vous pouvez également utiliser cette approche dans les scripts bash (par exemple, ceux qui doivent s'exécuter dans un environnement virtuel spécifique). Exemple (ajouté au script bash):
if [ $CONDA_DEFAULT_ENV ] ## << note the spaces (important in BASH)!
then
printf 'venv: operating in tf-env, proceed ...'
else
printf 'Note: must run this script in tf-env venv'
exit
fi
Mise à jour 2 [novembre 2019]
Depuis mon article d'origine, je suis passé d'Anaconda venv (et Python lui-même a évolué dans des environnements virtuels à savoir ).
En réexaminant ce problème, voici du code Python mis à jour que vous pouvez insérer pour tester que vous travaillez dans un environnement virtuel Python spécifique (venv).
import os, re
try:
if re.search('py37', os.environ['VIRTUAL_ENV']):
pass
except KeyError:
print("\n\tPlease set the Python3 venv [alias: p3]!\n")
exit()
Voici un code explicatif.
[victoria@victoria ~]$ date; python --version
Thu 14 Nov 2019 11:27:02 AM PST
Python 3.8.0
[victoria@victoria ~]$ python
Python 3.8.0 (default, Oct 23 2019, 18:51:26)
[GCC 9.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os, re
>>> re.search('py37', os.environ['VIRTUAL_ENV'])
<re.Match object; span=(20, 24), match='py37'>
>>> try:
... if re.search('py37', os.environ['VIRTUAL_ENV']):
... print('\n\tOperating in Python3 venv, please proceed! :-)')
... except KeyError:
... print("\n\tPlease set the Python3 venv [alias: p3]!\n")
...
Please set the Python3 venv [alias: p3]!
>>> [Ctrl-d]
now exiting EditableBufferInteractiveConsole...
[victoria@victoria ~]$ p3
[Python 3.7 venv (source activate py37)]
(py37) [victoria@victoria ~]$ python --version
Python 3.8.0
(py37) [victoria@victoria ~]$ env | grep -i virtual
VIRTUAL_ENV=/home/victoria/venv/py37
(py37) [victoria@victoria ~]$ python
Python 3.8.0 (default, Oct 23 2019, 18:51:26)
[GCC 9.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os, re
>>> try:
... if re.search('py37', os.environ['VIRTUAL_ENV']):
... print('\n\tOperating in Python3 venv, please proceed! :-)')
... except KeyError:
... print("\n\tPlease set the Python3 venv [alias: p3]!\n")
...
Operating in Python3 venv, please proceed! :-)
>>>
Le moyen le plus simple est de simplement lancer: which python
si vous êtes dans un virtualenv, il pointera vers son python au lieu du global
(édité) J'ai trouvé ça, qu'en pensez-vous? (il retourne également le chemin de base de venv et fonctionne même pour les documents de lecture 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'] + '/../')
Il y a déjà beaucoup de bonnes méthodes publiées ici, mais en ajoutant juste une de plus:
import site
site.getsitepackages()
vous indique où sont pip
installés les packages.
site.getsitepackages()
génère un répertoire qui n'est pas celui du système, vous pouvez en déduire que vous êtes dans un environnement virtuel.
virtualenv
.
venv
vous utilisez.
Ce n'est pas à l'épreuve des balles mais pour les environnements UNIX, test simple comme
if run("which python3").find("venv") == -1:
# something when not executed from venv
fonctionne très bien pour moi. C'est plus simple que de tester un attribut existant et, de toute façon, vous devez nommer votre répertoire venvvenv
.
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".
Une solution potentielle est:
os.access(sys.executable, os.W_OK)
Dans mon cas, je voulais juste détecter si je pouvais installer des éléments avec pip tel quel. Bien que ce ne soit pas la bonne solution dans tous les cas, pensez simplement à vérifier si vous avez des autorisations d'é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'])
C'est une vieille question, mais trop d'exemples ci-dessus sont trop compliqués.
Keep It Simple: (dans Jupyter Notebook ou le terminal 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'
envs
dans ce chemin, cela cessera de fonctionner lorsque vous passerez d’anaconda à virtualenv
ou pipenv
.