Entornos virtuales y dependencias: cada proyecto en su propia burbuja
Aprende a usar entornos virtuales en Python para aislar dependencias, trabajar con venv y pip, registrar paquetes con requirements.txt y reconstruir proyectos de forma reproducible.
Contenido de la guía ⌄
- El problema: todos los proyectos comparten la misma habitación
- Qué es realmente un entorno virtual
- Crear la burbuja de un proyecto
- Qué cambia cuando activas un entorno
- pip y el problema del paquete equivocado
- Dependencias directas y dependencias transitivas
- Cómo registrar las dependencias de un proyecto
El problema: todos los proyectos comparten la misma habitación
Instalar una biblioteca en Python parece sencillo: ejecutamos un comando, comenzamos a importarla y seguimos programando. El problema aparece cuando nuestra computadora deja de tener un solo proyecto.
Imagina que estás trabajando en dos aplicaciones completamente independientes. Una es un proyecto web y la otra procesa datos.
Tiene su propio código, su propio ritmo de actualización y sus propias dependencias.
También necesita bibliotecas de Python, pero no necesariamente las mismas versiones que el proyecto web.
Mientras ambos utilizan exactamente las mismas versiones puede parecer que no existe ningún problema. Pero ahora supongamos que los dos necesitan una misma biblioteca y cada uno depende de una versión diferente.
Si ambos proyectos utilizan el mismo espacio de paquetes de Python, ¿qué versión dejamos instalada?
Para entender el conflicto, pensemos primero en una instalación de Python donde todos nuestros proyectos terminan utilizando el mismo conjunto de paquetes instalados.
En este modelo, los proyectos no poseen realmente sus propias dependencias. Todos miran hacia un mismo espacio compartido.
Eso significa que una decisión aparentemente local puede afectar a otros proyectos. Actualizar una biblioteca para solucionar un problema en una aplicación puede introducir un cambio incompatible en otra.
El problema no es que Python permita instalar paquetes. El problema es hacer que proyectos independientes dependan accidentalmente del mismo conjunto mutable de paquetes.
Veamos el conflicto de una forma más concreta.
Fue creado y probado utilizando:
Utiliza una funcionalidad disponible en:
Si instalamos la versión nueva para satisfacer al Proyecto B, podríamos modificar el entorno sobre el que depende el Proyecto A.
Podríamos intentar mantener siempre todos nuestros proyectos sincronizados, pero esa estrategia se vuelve frágil conforme crecen la cantidad de aplicaciones y dependencias.
La alternativa es cambiar la pregunta.
“¿Qué versión de esta biblioteca debe tener mi computadora?”, preguntaremos: “¿Qué versión necesita este proyecto?”
Esa separación es precisamente la idea detrás de los entornos virtuales de Python: permitir que cada proyecto mantenga su propio contexto de dependencias sin obligar a los demás a tomar las mismas decisiones.
Qué es realmente un entorno virtual
Un entorno virtual es un contexto de Python asociado a un proyecto, con su propio intérprete y su propia ubicación para instalar paquetes.
La idea es sencilla: en lugar de hacer que todos nuestros proyectos dependan del mismo conjunto de bibliotecas instaladas, cada proyecto puede mantener las suyas por separado.
Podemos imaginarlo como una burbuja alrededor de las herramientas Python que necesita ese proyecto.
El entorno virtual no intenta aislar toda la computadora. Su objetivo es aislar el contexto Python utilizado por el proyecto.
La palabra virtual puede hacer pensar que estamos creando una computadora completa dentro de otra, pero un entorno virtual de Python es mucho más pequeño y específico.
El intérprete utilizado por el proyecto, los ejecutables asociados al entorno y el lugar donde se instalan sus paquetes Python.
El sistema operativo, la CPU, la memoria RAM, la red ni todos los procesos de la computadora.
Cada entorno puede tener versiones diferentes.
El proyecto puede apuntar al Python contenido en su entorno.
Sigue siendo el mismo.
También sigue siendo compartido.
Un entorno virtual de Python no cumple el mismo propósito que Docker ni que una máquina virtual. Aquí nos interesa aislar principalmente Python y sus dependencias.
Normalmente guardaremos el entorno dentro del propio directorio del proyecto utilizando una carpeta llamada .venv.
Dentro de .venv Python crea la estructura necesaria para que ese proyecto disponga de su propio contexto.
El entorno contiene un intérprete asociado a esa instalación de Python.
Permite instalar paquetes dentro de ese entorno.
Las dependencias del proyecto viven separadas de otros entornos.
Nuestro código permanece fuera de .venv.
.venv contiene el entorno. Nuestro código sigue perteneciendo al proyecto.
Crear la burbuja de un proyecto
Python incluye el módulo venv, que puede crear un entorno virtual sin instalar una herramienta adicional.
El comando que utilizaremos es:
Aunque al principio parece una instrucción para memorizar, cada parte tiene un significado concreto.
Es el intérprete con el que vamos a crear el entorno.
Le indica a Python que ejecute un módulo.
Es el módulo de la biblioteca estándar encargado de crear el entorno.
Es el directorio donde queremos guardar ese entorno.
El entorno se crea utilizando una instalación de Python existente. No estamos descargando un sistema operativo ni construyendo una máquina virtual completa.
# Dentro de la carpeta del proyecto
python -m venv .venv
# Activar el entorno en PowerShell
.\.venv\Scripts\Activate.ps1
# Dentro de la carpeta del proyecto
python3 -m venv .venv
# Activar el entorno
source .venv/bin/activate
El nombre .venv es una convención, no una palabra reservada de Python.
Podríamos crear exactamente el mismo tipo de entorno utilizando otros nombres:
Por ejemplo:
crearía el entorno dentro de una carpeta llamada entorno.
En esta guía utilizaremos .venv porque comunica claramente su propósito, mantiene el entorno dentro del proyecto y es una convención fácil de reconocer en editores y herramientas.
Nuestro proyecto empieza entonces a verse así:
Pero todavía queda una pregunta importante: ¿qué hay realmente dentro de esa burbuja y qué pertenece al proyecto?
Qué cambia cuando activas un entorno
Crear .venv y activarlo son dos operaciones diferentes. La primera construye el entorno; la segunda hace que nuestra terminal empiece a utilizarlo de forma cómoda.
Cuando activamos un entorno virtual no estamos “encendiendo” una máquina separada. Lo que ocurre principalmente es que la sesión de la terminal modifica la forma en que busca ejecutables.
Activar el entorno hace que comandos como python y pip puedan resolverse primero hacia los ejecutables contenidos en .venv.
Podemos imaginar el cambio como una modificación en el camino que sigue la terminal cuando escribimos python.
Muchos shells también modifican el indicador de la terminal para mostrar algo parecido a:
Esa marca es útil, pero no debería ser nuestra única prueba de que estamos utilizando el intérprete correcto.
# Windows / PowerShell
where.exe python
python -c "import sys; print(sys.executable)"
# Linux / macOS
command -v python
python -c "import sys; print(sys.executable)"
El segundo comando es especialmente útil porque no depende de interpretar visualmente el prompt de la terminal.
Python nos responde directamente con la ruta del intérprete que está ejecutando el comando.
La ruta apuntará normalmente a una instalación de Python disponible en el sistema.
La ruta debería apuntar al intérprete ubicado dentro de .venv.
Si tienes dudas sobre qué entorno estás utilizando, no adivines: pregúntale a Python cuál es su ejecutable con sys.executable.
Hay un detalle que ayuda a entender todavía mejor qué significa activar un entorno: no es obligatorio activarlo para utilizarlo.
Podemos ejecutar directamente el intérprete que está dentro de .venv.
.venv\Scripts\python.exe
.venv/bin/python
Principalmente para no tener que escribir la ruta completa del intérprete cada vez. La activación prepara la sesión de la terminal para que podamos trabajar cómodamente con ese entorno.
pip y el problema del paquete equivocado
Ya sabemos comprobar qué Python estamos utilizando. Ahora aparece una pregunta igual de importante: cuando instalamos una biblioteca, ¿en qué Python la estamos instalando?
Es común encontrar instrucciones como:
El comando puede funcionar perfectamente, pero todavía existe una pregunta que no deberíamos ignorar:
¿Ese pip pertenece al mismo Python con el que vamos a ejecutar nuestro proyecto?
Si nuestra computadora tiene varias instalaciones de Python, varios entornos virtuales o configuraciones diferentes del PATH, asumirlo puede llevarnos a instalar el paquete en un lugar y ejecutar el programa desde otro.
# Forma explícita que utilizaremos en esta guía
python -m pip install requests
# También puede funcionar, pero depende de qué pip resuelva la terminal
pip install requests
La forma python -m pip hace explícita una relación muy importante.
La opción -m le pide al intérprete que ejecute el módulo pip. De esa forma primero decidimos qué Python utilizar y después dejamos que ese mismo Python gestione sus paquetes.
En esta guía preferiremos python -m pip porque hace visible la relación entre el intérprete y el gestor de paquetes.
Ejecutar simplemente pip es válido cuando sabemos exactamente qué ejecutable está resolviendo nuestra terminal. La forma con python -m pip reduce esa ambigüedad.
Podemos verificar la relación entre Python y pip con un comando muy sencillo:
La salida suele mostrar tres piezas de información útiles:
Nos indica qué versión del gestor está ejecutándose.
Permite comprobar dónde está instalado.
Nos ayuda a confirmar qué instalación está gestionando esos paquetes.
Si estamos dentro del entorno correcto, esperamos reconocerlo en la ruta.
Podemos combinar esta comprobación con la que ya conocemos:
Tanto el intérprete como el lugar donde pip gestiona paquetes deberían corresponder al entorno virtual de nuestro proyecto.
Llegados a este punto ya podemos visualizar una cadena completa: el proyecto selecciona un Python, ese Python ejecuta pip y pip instala las dependencias dentro de ese entorno.
Dependencias directas y dependencias transitivas
Cuando instalamos una biblioteca, el entorno puede terminar conteniendo más paquetes de los que nosotros elegimos conscientemente.
Supongamos que nuestro proyecto necesita una biblioteca llamada paquete-web.
Nosotros decidimos utilizar paquete-web, pero esa biblioteca también puede necesitar otras para funcionar.
Una dependencia puede tener sus propias dependencias. Por eso un único comando de instalación puede añadir varios paquetes al entorno.
Es una biblioteca que nuestro proyecto decide utilizar directamente.
Es una biblioteca que otra dependencia necesita para poder funcionar.
Podemos imaginarlo así:
Desde la perspectiva de nuestro proyecto, paquete-web es una dependencia directa. Las otras aparecen indirectamente porque paquete-web las necesita.
El contenido de un entorno virtual puede ser bastante mayor que la lista de bibliotecas que recordamos haber instalado manualmente.
# Instalar una dependencia directa
python -m pip install requests
# Ver todos los paquetes presentes en el entorno
python -m pip list
Cómo registrar las dependencias de un proyecto
Un entorno virtual resuelve el aislamiento local, pero todavía necesitamos responder otra pregunta: ¿cómo sabrá otra persona qué debe instalar para reconstruir nuestro proyecto?
La carpeta .venv contiene los paquetes instalados en nuestra computadora, pero no queremos depender de esa carpeta para siempre.
Una de las formas más sencillas y extendidas de registrar ese estado en proyectos Python es mediante un archivo:
# Guardar los paquetes instalados y sus versiones
python -m pip freeze > requirements.txt
Comentarios y valoraciones
No hay comentarios aún. ¡Sé el primero en opinar!