¿Es posible determinar si el script actual se está ejecutando dentro de un entorno virtualenv?
¿Es posible determinar si el script actual se está ejecutando dentro de un entorno virtualenv?
Respuestas:
AFAIK la forma más confiable de verificar esto (y la forma en que se usa internamente en virtualenv y en pip) es verificar la existencia de sys.real_prefix
:
import sys
if hasattr(sys, 'real_prefix'):
#...
Dentro de un virtualenv, sys.prefix
apunta al directorio virtualenv, y sys.real_prefix
apunta al prefijo "real" del sistema de Python (a menudo /usr
o /usr/local
o algo así).
Fuera de un virtualenv, sys.real_prefix
no debería existir.
Usar la VIRTUAL_ENV
variable de entorno no es confiable. Está configurado por el activate
script de shell virtualenv , pero un virtualenv puede usarse sin activación ejecutando directamente un ejecutable desde el directorio virtualenv bin/
(o Scripts
), en cuyo caso $VIRTUAL_ENV
no se establecerá.
PYTHON_ENV=$(python -c "import sys; sys.stdout.write('1') if hasattr(sys, 'real_prefix') else sys.stdout.write('0')")
Intenta usar pip -V
(nota mayúscula V)
Si está ejecutando el entorno virtual. mostrará el camino a la ubicación del entorno.
virtualenv
mucho, es posible que esto pueda fallar o mentirte. Si está mintiendo, puedes hacerlo find /path/to/venv/ -type f -exec sed -ie "s:/old/path/to/venv:/path/to/venv:g" {} \+
. Si está fallando (obtuve "datos incorrectos del mariscal"), deberá borrar los archivos .pyc find /path/to/venv -type f -name "*.pyc" -exec rm {} \+
(no se preocupe, se reconstruirán automáticamente).
...\lib\site-packages
en %PATH%
. Entonces devolverá un falso positivo en ese caso.
Esta es una mejora de la respuesta aceptada por Carl Meyer . Funciona con virtualenv para Python 3 y 2 y también para el módulo venv en Python 3:
import sys
def is_venv():
return (hasattr(sys, 'real_prefix') or
(hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix))
El cheque para sys.real_prefix
cubiertas virtualenv, la igualdad de no vacías sys.base_prefix
con sys.prefix
cubiertas venv.
Considere un script que usa la función de esta manera:
if is_venv():
print('inside virtualenv or venv')
else:
print('outside virtualenv or venv')
Y la siguiente invocación:
$ 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
. Sólo digo'.
pipenv
entornos virtuales creados.
Verifique la $VIRTUAL_ENV
variable de entorno.
La $VIRTUAL_ENV
variable de entorno contiene el directorio del entorno virtual cuando se encuentra en un entorno virtual activo.
>>> import os
>>> os.environ['VIRTUAL_ENV']
'/some/path/project/venv'
Una vez que ejecuta deactivate
/ abandona el entorno virtual, la $VIRTUAL_ENV
variable se borrará / vaciará. Python generará un KeyError
porque la variable de entorno no estaba configurada.
>>> 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'
Estas mismas comprobaciones de variables de entorno, por supuesto, también se pueden hacer fuera del script de Python, en el shell.
virtualenv
virtualenv como para un venv
virtualenv.
De acuerdo con virtualenv pep en http://www.python.org/dev/peps/pep-0405/#specification , puede usar sys.prefix en lugar de os.environ ['VIRTUAL_ENV'].
sys.real_prefix no existe en mi virtualenv y lo mismo ocurre con sys.base_prefix.
sys.real_prefix
.
env |grep VIRTUAL_ENV |wc -l
que devolverá un 1 si está en un venv o un 0 si no.
[[ -n $VIRTUAL_ENV ]] && echo virtualenv
o [[ -z $VIRTUAL_ENV ]] && echo not virtualenv
según sus necesidades.
Para verificar si está dentro de Virtualenv:
import os
if os.getenv('VIRTUAL_ENV'):
print('Using Virtualenv')
else:
print('Not using Virtualenv')
También puede obtener más datos sobre su entorno:
import sys
import os
print(f'Python Executable: {sys.executable}')
print(f'Python Version: {sys.version}')
print(f'Virtualenv: {os.getenv("VIRTUAL_ENV")}')
Aquí hay varias buenas respuestas, y algunas menos robustas. Aquí hay una descripción general.
No confíe en la ubicación de Python o la site-packages
carpeta.
Si se configuran en ubicaciones no estándar, eso no significa que esté realmente en un entorno virtual. Los usuarios pueden tener más de una versión de Python instalada, y no siempre están donde espera que estén.
Evita mirar:
sys.executable
sys.prefix
pip -V
which python
Además, no se verifique la presencia de venv
, .venv
o envs
en cualquiera de estos caminos. Esto se romperá para entornos con una ubicación más única. Por ejemplo,
Pipenv usa valores hash como nombre para sus entornos.
VIRTUAL_ENV
Variable ambientalAmbos virtualenv
y venv
establecer la variable de entorno $VIRTUAL_ENV
al activar un entorno. Ver PEP 405 .
Puede leer esta variable en scripts de shell o usar este código de Python para determinar si está configurado.
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"))
El problema es que esto sólo funciona cuando el ambiente se activa por el activate
script de shell.
Puede iniciar los scripts del entorno sin activar el entorno , por lo que si eso le preocupa, debe usar un método diferente.
sys.base_prefix
virtualenv
, venv
Y el pyvenv
punto sys.prefix
a la de Python instalado en el interior de la virtualenv como era de esperar.
Al mismo tiempo, el valor original de sys.prefix
también está disponible como sys.base_prefix
.
Podemos usar eso para detectar si estamos en 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
Ahora tenga cuidado, virtualenv
antes de que la versión 20 no se configurara, sys.base_prefix
sino que se configuraba sys.real_prefix
.
Entonces, para estar seguro, verifique ambos como se sugiere en la respuesta 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 está utilizando entornos virtuales Anaconda, verifique la respuesta de Victoria Stuart .
running_in_virtualenv = sys.*base_*prefix != sys.prefix
if hasattr(sys, 'real_prefix'):
prueba, que ya no funcionaba.
Puede hacer which python
y ver si apunta al que está en el entorno virtual.
which
no está disponible por defecto en Windows. En su where
lugar, puede usar en Windows o emplear whichcraft . O mira sys.executable
. Pero aún así, hay mejores métodos.
Yo uso habitualmente varios entornos virtuales instalados por Anaconda (venv). Este fragmento de código / ejemplos le permite determinar si se encuentra o no en un venv (o en el entorno de su sistema), y también puede requerir un venv específico para su script.
Agregar al script de Python (fragmento de código):
# ----------------------------------------------------------------------------
# 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! ... ]
Ejemplo:
$ 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) $
Actualización 1 - uso en scripts bash:
También puede usar este enfoque en scripts de bash (por ejemplo, aquellos que deben ejecutarse en un entorno virtual específico). Ejemplo (agregado al 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
Actualización 2 [Nov 2019]
Desde mi publicación original, me mudé de Anaconda venv (y Python ha evolucionado en entornos virtuales viz-a-viz ).
Reexaminando este problema, aquí hay un código Python actualizado que puede insertar para probar que está operando en un entorno virtual Python específico (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()
Aquí hay un código explicativo.
[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! :-)
>>>
La forma más fácil es simplemente ejecutar: which python
si está en un virtualenv, apuntará a su pitón en lugar del global.
(editado) Encontré de esa manera, ¿qué piensas de eso? (también devuelve la ruta de base de venv y funciona incluso para readthedocs donde no se verifica la variable env ):
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'] + '/../')
Ya hay muchos métodos excelentes publicados aquí, pero solo agregando uno más:
import site
site.getsitepackages()
te dice dónde están pip
instalados los paquetes.
site.getsitepackages()
genera un directorio que no es el del sistema, puede deducir que se encuentra en un entorno virtual.
virtualenv
.
venv
estás usando.
En el sistema operativo Windows, ve algo como esto:
C:\Users\yourusername\virtualEnvName\Scripts>activate
(virtualEnvName) C:\Users\yourusername\virtualEnvName\Scripts>
Los paréntesis significan que en realidad se encuentra en el entorno virtual llamado "virtualEnvName".
Una posible solución es:
os.access(sys.executable, os.W_OK)
En mi caso, realmente solo quería detectar si podía instalar elementos con pip tal cual. Si bien puede no ser la solución correcta para todos los casos, considere simplemente verificar si tiene permisos de escritura para la ubicación del ejecutable de Python.
Nota: esto funciona en todas las versiones de Python, pero también regresa True
si ejecuta el sistema Python con sudo
. Aquí hay un caso de uso potencial:
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'])
Esta es una vieja pregunta, pero muchos ejemplos anteriores son demasiado complicados.
Keep It Simple: (en el terminal Jupyter Notebook o Python 3.7.1 en 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
esa ruta, dejará de funcionar cuando se mueva de anaconda a virtualenv
o pipenv
.