Managing Libraries in Python
La forma más popular de instalar paquetes externos en Python es utilizando pip. Según el autor, pip
es una abreviatura recursiva de "pip installs packages", lo que significa que la definición hace referencia a la propia abreviatura, creando un bucle. Muy gracioso, de hecho. De cualquier manera, pip
es el nombre del módulo de Python que gestiona paquetes externos de Python. Con pip
, podemos instalar, desinstalar y actualizar paquetes de Python. A diferencia de descargar e instalar complementos para un navegador o editor de texto, no es común "buscar" paquetes de Python.
Programar se trata de usar la herramienta adecuada para el trabajo, así que no te preocupes por buscar paquetes para instalar. El enfoque correcto, y probablemente también el más común, es descubrir cómo hacer algo
y obtener recomendaciones de paquetes en el proceso. La documentación de estos paquetes - la mayoría de las veces en sus sitios web - normalmente muestra ejemplos de cómo instalar el paquete para los usuarios primerizos. Veamos también cómo gestionar paquetes.
Algunos argumentos útiles para pip
que veremos son install
y la flag --upgrade
, uninstall
y freeze
. El argumento install
permite a los usuarios instalar nuevos paquetes o actualizar los paquetes existentes a la última versión (si se proporciona el parámetro --upgrade
). El argumento uninstall
como sugiere el nombre, elimina el paquete del sistema. Sorprendentemente, el comando freeze
no tiene nada que ver con detener algo o con películas policiales cursis. Este imprime una lista de todos los paquetes instalados (vía pip) y sus dependencias. Podemos ejecutar los comandos usando pip
directamente o como un módulo de Python. A continuación se muestran algunos ejemplos de cómo podría verse esto.
Installing "flask" with Pip
# Syntax: python3 -m pip install [package]
python3 -m pip install flask
Collecting flask
Using cached Flask-1.1.2-py2.py3-none-any.whl (94 kB)
Collecting Werkzeug>=0.15
Using cached Werkzeug-1.0.1-py2.py3-none-any.whl (298 kB)
Collecting itsdangerous>=0.24
Using cached itsdangerous-1.1.0-py2.py3-none-any.whl (16 kB)
Collecting click>=5.1
Using cached click-7.1.2-py2.py3-none-any.whl (82 kB)
Collecting Jinja2>=2.10.1
Downloading Jinja2-2.11.3-py2.py3-none-any.whl (125 kB)
|████████████████████████████████| 125 kB 7.0 MB/s
Collecting MarkupSafe>=0.23
Downloading MarkupSafe-1.1.1-cp39-cp39-macosx_10_9_x86_64.whl (16 kB)
Installing collected packages: Werkzeug, itsdangerous, click, MarkupSafe, Jinja2, flask
Successfully installed Jinja2-2.11.3 MarkupSafe-1.1.1 Werkzeug-1.0.1 click-7.1.2 flask-1.1.2 itsdangerous-1.1.0
Como se puede ver, aunque solo pedimos instalar flask
, un paquete brillante para ejecutar servidores web basados en Python (al igual que bottle
- similar pero diferente), también obtenemos una multitud de otros paquetes que son requisitos de flask
. Podríamos intentar actualizarlo, pero ya se nos indica que estamos ejecutando la última versión.
Upgrading Packages
python3 -m pip install --upgrade flask
Requirement already up-to-date: flask in /usr/local/lib/python3.9/site-packages (1.1.2)
Requirement already satisfied, skipping upgrade: itsdangerous>=0.24 in /usr/local/lib/python3.9/site-packages (from flask) (1.1.0)
Requirement already satisfied, skipping upg...
<SNIP>
Si quisiéramos desinstalar un paquete en particular, podríamos hacerlo ejecutando:
Uninstalling Packages
pip uninstall [package]
Veamos qué está instalado actualmente ejecutando pip
con el argumento freeze
. Como algunos de ellos son dependencias de flask
, dejaremos la desinstalación en sí como "extras". Ten en cuenta que si elegimos desinstalar un paquete de dependencia, el paquete principal probablemente dejará de funcionar. También observa que freeze
puede producir resultados diferentes dependiendo de la máquina y la versión de Python.
Listing the Installed Packages
# Syntax: python3 -m pip freeze [package]
python3 -m pip freeze
click==7.1.2
Flask==1.1.2
itsdangerous==1.1.0
Jinja2==2.11.3
MarkupSafe==1.1.1
protobuf==3.13.0
pynput==1.7.3
pyobjc-core==7.1
pyobjc-framework-Cocoa==7.1
pyobjc-framework-Quartz==7.1
six==1.15.0
Werkzeug==1.0.1
Esta lista de paquetes instalados podría ser útil para compartirla con otra persona para usar nuestros scripts o ayudar con el desarrollo. De esta manera, sabrán qué paquetes deben instalar (e incluso qué versiones).
Resulta que pip
admite mantener paquetes desde un archivo de requisitos. Este archivo, a menudo llamado literalmente requirements.txt
, contiene una lista de todos los paquetes necesarios para ejecutar el script con éxito. El formato es bastante simple. Copiaríamos el resultado de freeze
y lo guardaríamos como un archivo de requisitos. Sin embargo, es un poco excesivo, y no necesitamos saber ni listar las dependencias de los paquetes que necesitamos.
Por ejemplo, supongamos que nos gustaría usar flask
y click
(regresaremos a click
más adelante). Si no conocemos los requisitos de versión o no nos importa, simplemente podríamos listar los paquetes uno tras otro y guardarlos así:
Example requirements.txt
cat requirements.txt
flask
click
Luego, para instalar todos los paquetes en el archivo de requisitos, escribiríamos:
Install from requirements.txt
python3 -m pip install -r requirements.txt
Esto recorrerá cada uno de los requisitos e instalará la última versión disponible y permitida.
Supongamos que queríamos explícitamente la versión 1.1.2 de flask
. Todo lo que teníamos que hacer era reemplazar flask
con flask==1.1.2
en el archivo de requisitos, al igual que el resultado del comando pip freeze
.
A continuación se muestra una lista de operadores comunes de comparación de versiones que es muy probable que encontremos en proyectos más grandes de Python (lee más en PEP 440).
Comparison Operator | Description |
---|---|
== |
Cláusula de coincidencia de versión |
<= / >= |
Cláusula de comparación ordenada inclusiva |
< / > |
Cláusula de comparación ordenada exclusiva |
Nos permiten especificar, en el archivo de requisitos, nuestras necesidades exactas para las versiones. Por ejemplo, si sabemos que algún paquete xyz
es vulnerable a explotación en las versiones 1.0.4 e inferiores, podemos especificar en nuestro archivo de requisitos que necesitamos xyz>=1.0.5
.
También es bastante común que nuevas actualizaciones de un paquete rompan el código actual (por ejemplo, paquetes que dependen de otros sistemas de terceros como la API de Discord bot para Python). En estos casos, podemos forzar una versión anterior de un paquete. Al mismo tiempo, los cambios necesarios se estaban trabajando con el operador <
o <=
.
Para no profundizar demasiado en este tema desde el principio, volveremos a él más adelante en el módulo. Por ahora, sigamos con algunos requisitos previos para nuestro primer proyecto.