Primeros pasos con Python

Después de instalar Python ¿por dónde empiezo? ¿dónde instalo los paquetes? ¿uso pipenv o poetry? ¿VSCode o PyCharm?

Instalar Python es muy sencillo, basta con descargar el instalador desde la página oficial y seguir el asistente. Las únicas decisiones relevantes son si agregar o no al %PATH% Python y si lo instalaremos para todos los usuarios o sólo para el usuario actual.

Si lo instalas para todos los usuarios se intalará en C:\Program Files\Python<Version> y si lo instalas para el usuario actual lo hará en %LOCALAPPDATA%\Programs\Python\Python<Version>. <Version> será algo como 38, 39, 310, etc.

Si agregas Python al %PATH% se agregarán las siguientes rutas (%LOCALAPPDATA% es porque asumo has elegido instalar sólo para el usuario actual) %LOCALAPPDATA%\Programs\Python\Python<Version>\Scripts\ y %LOCALAPPDATA%\Programs\Python\Python<Version>.

Fíjate que es perfectamente válido instalar múltiples versiones de Python, luego podrías acabar con un montón de rutas en tu %PATH%. Además, el instalador añade estas rutas al principio de %PATH% y no entiende de versiones, luego si instalas primero 3.10 y luego 3.9, tendrás primero las rutas de 3.9 en el %PATH%. Siéntente libre de cambiar el orden de estas rutas en la variable de entorno.

En cualquier caso, si quieres saber que versión de Python cogerá la shell por defecto, bastaría con ejecutar python --version. Con where python puedes ver además, en que rutas han encontrado Windows python.exe y la primera ruta que aparezca será de donde se ejecute. Si estás en PowerShell usa where.exe porque where es una palabra reservada del lenguaje y no la reconocerá en ese contexto.

En Windows, se instala además py Python launcher for Windows. Con py --list puedes ver que versiones tienes instaladas y cuál es la versión por defecto para py (que nada tiene que ver con %PATH%, para py es siempre la más reciente si no lo especificamos lo contrario). La verdad es que no uso mucho py, salvo para ver las versiones y jugar con el shebang de Python, esto es tener un fichero .py y poner en la primera línea algo como #!python3.9.

A mí no terminó de convencerme, pero pyenv-win puede ser tu amigo y ayudarte en la instalación, activación y desistalación de mútiples versiones de Python en una misma máquina.

En cualquier caso y con Python ya instalado, lo que toca ahora es instalar paquetes.

Primero vamos a hablar de paquetes cuyo uso principal es ser usados como herramientas de línea de comandos, por ejemplo httpie.

Puedo instalarlo con pip que es gestor de paquetes de Python. Tan sencillo como pip install httpie y ya tendrás disponible el comando http y https en tu terminal.

pip funciona bien, no seré yo quien diga lo contrario, pero la gestión que hace de las dependencias podría ser mejorable. Si ahora haces pip list verás un montón de paquetes (entre ellos httpie), pero hay otro montón de ellos que son dependencias de httpie y tú no eres conscientes de haberlos instalado (son dependencias de httpie). No hay en pip (al menos que yo sepa) algo parecido a npm list -g --depth=0 para ver sólo los paquetes instalados explícitamente y no sus dependencias. Además de eso, si hago un pip uninstall httpie sólo desinstalará el paquete httpie pero no sus dependencias, y se vuelves a hacer pip list verás ahí un montón de paquetes que parecen no tener dueño. Para solucionar esto, a mí me gusta instalar pipdeptree que sacará el mismo listado que pip list pero de forma jerárquica y también pip-autoremove que desintalará un paquete y sus dependencias sin uso. Yo creo que todo esto debería venir de serie, pero bueno.

Si volvemos al escenario donde tienes múltiples versiones de Python instaladas en tu equipo, cabe mencionar que pip usará la versión que encuentre según %PATH%, es decir, lo que instales con el pip de 3.10 no estará en los paquetes de 3.9. Para herramientas globales te puede dar un poco igual (al final tu tendrás tu comando de turno disponible en la línea de comandos), pero era importante mencionarlo. Por otro lado, si quieres ejecutar una versión en concreto de pip (y no la que encuentra %PATH%), puedes usar py -<Version> -m pip list.

Como muchas veces acabarás con cierto galimatías con los paquetes en la instalación del sistema, me guardo este comando como oro en paño para dejarlo todo más limpio que una patena.

pip list --format freeze | % { $_.Substring(0, $_.IndexOf("==")) } | ? { @('pip','setuptools','wheel') -NotContains $_ } | % { pip uninstall $_ --yes }

De todas formas y como recomendación final para la gestión global de paquetes/herramientas, te diría que usases pipx (me recuerda a npx de Node.js). pipx instalará el paquete (y todas sus dependencias) en un entorno virtual propio. Fácil y seguro.

Llegados a este punto ya tenemos Python instalado y con pipx somos capaces de instalar herramientas globales sin miedo a contaminar la instalación global de Python, pero el principal uso de Python es crear programas y de eso todavía no hemos hablado.

Para desarrollar en Python, tarde o temprano necesitarás instalar paquetes (ahora ya no como herramientas sino como librerías para usar en tu código). Pues bien, nadie instala esos paquetes en global, sería una temeridad, acabarías teniendo conflictos de versiones y, básicamente, es una mala práctica y se desaconseja. No lo hagas. Para solucionar esto se inventaron los entornos virtuales.

Un entorno virtual es básicamente una copia del interprete de Python (python.exe, entre otras muchos ficheros…) y un lugar aislado donde instalar paquetes sin riesgo de contanimar el espacio global ni otros entornos virtuales.

¿Y cómo creo un entorno virtual? Si quieres ir con lo puesto y no depender de nadie (tan sólo de la standard library) puedes usar el módulo venv. Sin embargo, hoy en día, la norma es usar pipenv o poetry, que no sólo permiten crear entornos virtuales sino que también te ayudan con la gestión de las dependencias de los paquetes, a crear un paquete de salida, etc.

poetry es más moderno que pipenv y hace honor a las recomendaciones oficiales más recientes. Ahora mismo sería mi primera elección. No obstante, pipenv está bastante extendido y sigue funcionando bien. Si vas a usar pipenv te recomienda echar un vistazo a este repositorio que te ayudará con todo el boilerplate necesario a la hora de crear un paquete (incluido un workflow de GitHub para su publicación en un feed de paquetes de Azure DevOps).

Después de instalar pipenv con pipx install pipenv, podemos crear un proyecto y ejecutarlo con:

mkdir PythonApp1
cd .\PythonApp1\
pipenv shell # create the virtual environment
pipenv install requests # install a dependency, it will create the file Pipfile.lock
echo "import requests`nr = requests.get('https://jsonplaceholder.typicode.com/users')`nprint(r.json())" > main.py # an example
python main.py # execute the program

Si la instrucción de echo no te gusta (un poco forzada por el ejemplo, todo hay que decirlo), aquí está el código que usaremos para las pruebas:

import requests
r = requests.get('https://jsonplaceholder.typicode.com/users')
print(r.json())

Lo interesante es que, después de haber activado el entorno virtual, si hacemos where.exe python veremos que ya no apunta a python del %PATH%, sino a la copia que está en nuestro entorno virtual. De hecho, pip list dentro del entorno virtual (o mejor pipenv graph) mostrará requests, pero fuera del entorno virtual (no estando activado, nada tiene que ver con el directorio actual donde nos encontremos), ni rastro de requests. ¡Bien! Hemos conseguido aislar esta dependencia y no contaminar la intalación del sistema, ¡prueba superada!.

Si estás trabajando con PowerShell, te podría merecer la pena configurar tu perfil para que cambie el prompt al activar un entorno virtual. Ejecutar code $PROFILE y copia y pega este código:

function Prompt() {
    $prompt = "PS "
    # if ($env:PIPENV_ACTIVE -eq 1 -or $env:POETRY_ACTIVE -eq 1) {
    if ($env:PIPENV_ACTIVE -eq 1) {
        $prompt = "(" + (($env:VIRTUAL_ENV -split "\\")[-1] -split "-")[0] + ") "
    }      
    $prompt += $pwd.Path.Trim()
    Write-Host $prompt -NoNewline
    "> "
}

Ahora tu prompt (después de haber abierto y cerrado tu consola o haber ejecutado . $PROFILE) debería mostrarse algo así: (PythonApp1) C:\Temp\PythonApp1>. Ya sí queda claro que estás dentro de un entorno virtual.

Merece especial atención el fichero Pipfile.lock, que se creó al instalar el primer paquete. Este fichero es el equivalente al package-lock.json de Node.js o al packages.lock.json de .NET. Todos persiguen lo mismo, tener build repetibles, que cuando me clone el repositorio - o me baje los cambios más recientes - tenga en mi local las mismas dependencias que tenía el que subió los cambios. Este fichero es bien y tiene que ir al control de código fuente (no así el entorno virtual que lo puedes eliminar y recrear las veces que sean necesarias).

Con poetry (y después de haberlo instalado con pipx install poetry) los pasos a seguir son los siguientes:

poetry new PythonApp2
cd .\PythonApp2\
poetry install # install out-of-the-box dependencies and creates virtual environment
poetry shell # activate virtual environment
poetry add requests # add dependency
echo "import requests`nr = requests.get('https://jsonplaceholder.typicode.com/users')`nprint(r.json())" > .\pythonapp2\main.py # an example
python .\pythonapp2\main.py

Al igual que pipenv, poetrycreará un fichero para fijar las dependencias, esta vez llamado poetry.lock.

Por último (y por contestar a todas las preguntas que se lanzaron al comienzo del post) ¿VSCode o PyCharm? Hace unos meses te hubiera contestado que PyCharm para todo, pero ahora creo que la mejor opción (y estoy plenamente convencido de ello) es usar el IDE (o editor en el caso de VSCode) sólo para escribir, ejecutar, depurar… pero olvidarnos por completo de ellos en todo lo relativo a la creación del proyecto, gestión de paquetes y del entorno virtual. Tengo la sensación de que, sobre todo con PyCharm, queriendo ocultar todo lo que pasa tras bambalinas, te hace un flaco favor y luego te tocará hacer una pipeline en el servidor CI/CD de turno y las pasarás canutas si no tienes claro ciertos conceptos.

La única pregunta que ambos te van a hacer y tienes que tener claro, es ¿qué interprete de Python quieres usar?, y la respuesta es simplemente la ruta a la copia de python.exe que se guardó en tu entorno virtual, ni más ni menos.

En cuanto a la experiencia de edición de código, creo que PyCharm está más preparado para la vida moderna, tiene más refactorings automáticos y hereda mucha funcionalidad de IntelliJ IDEA. El resumen sería que es un “IDE”… y tampoco voy a descubrir yo ahora sus bondades. Sin embargo, VSCode es más inmediato y si tan sólo quieres ejecutar o depurar algo de forma rápida, es mucho más ligero. Además, si ya usas VSCode para otros lenguajes, te vas a llevar puesto todo lo que ya sabes de la herramienta.

Un saludo!


Ver también