Python / Compilar código y crear archivos EXE

Para distribuir código Python como EXE de Windows, PyInstaller puede reunir el programa, el entorno de ejecución de Python y las bibliotecas necesarias. Un archivo .pyc creado con py_compile contiene bytecode de Python, no un ejecutable autónomo de Windows. Compruebe primero el formato de carpeta y después cambie a un único EXE si lo necesita para aislar mejor los problemas.

Compilación a bytecode y empaquetado de EXE

py_compile convierte el código fuente en archivos de bytecode. PyInstaller recopila el intérprete y las dependencias en una aplicación distribuible. Esto no equivale a traducir un programa Python ordinario a código máquina nativo optimizado mediante C. Empaquetar no acelera automáticamente su ejecución ni oculta de forma segura el contenido del código.

El resultado depende del sistema operativo y la arquitectura. Construya los EXE de Windows en Windows; PyInstaller no es un compilador cruzado que los genere desde Linux con una opción. Compruebe los entornos compatibles y los requisitos de sus paquetes.

Preparar la carpeta y el entorno virtual en Windows

Use PowerShell en Windows con Python 3 y pip instalados. Abra un terminal en una carpeta de trabajo nueva y ejecute los comandos en orden. Si py -3 no está disponible, sustitúyalo en la primera línea por la ruta del Python instalado o un comando python que apunte a ese intérprete.

py -3 -m venv .venv
.\.venv\Scripts\python.exe -m pip install "pyinstaller==6.22.3"
.\.venv\Scripts\python.exe -m PyInstaller --version

.venv es el entorno virtual del proyecto. Los comandos posteriores invocan directamente su Python, por lo que no requieren activar scripts ni cambiar la política de ejecución de PowerShell. El ejemplo fija PyInstaller 6.22.3; si usa otra versión, revise de nuevo compatibilidad y opciones. Compruebe que la instalación termina correctamente y que el último comando muestra 6.22.3.

Instale las dependencias reales de la aplicación en ese mismo entorno. Construir desde un Python global con muchos paquetes innecesarios puede complicar el análisis y la gestión del resultado.

Guardar un ejemplo completo y generar bytecode

Cree hello.py en UTF-8 en la carpeta de trabajo:

print("Hello, packaging!")
Hello, packaging!

Ejecute primero el código fuente; debe mostrar el mensaje anterior.

.\.venv\Scripts\python.exe hello.py

Para probar únicamente la compilación a bytecode:

.\.venv\Scripts\python.exe -m py_compile hello.py

Si funciona, normalmente no hay salida y aparece un archivo como hello.cpython-312.pyc en __pycache__. La marca de versión depende de Python. Cambiar su nombre a EXE no lo hace autónomo: el bytecode sigue necesitando un entorno Python compatible.

Construir y distribuir una carpeta

Ejecute estos comandos desde la carpeta de trabajo, el segundo solo después de que la construcción termine correctamente.

.\.venv\Scripts\python.exe -m PyInstaller --onedir --name hello-folder hello.py
.\dist\hello-folder\hello-folder.exe

La salida es Hello, packaging!. Distribuya toda la carpeta dist\hello-folder, que contiene el EXE y sus archivos de soporte. Copiar solo el ejecutable puede dejar atrás bibliotecas necesarias. Los archivos auxiliares pueden estar bajo _internal; la estructura exacta depende de los paquetes y opciones.

build contiene archivos intermedios y de diagnóstico; hello-folder.spec registra la configuración. Los usuarios reciben el resultado de dist, no sus carpetas build o .venv. Consulte las opciones en la referencia de uso de PyInstaller.

Crear un solo EXE

Cuando funcione el formato de carpeta, empaquete el mismo código en un archivo único. Un nombre distinto permite conservar ambos resultados para compararlos.

.\.venv\Scripts\python.exe -m PyInstaller --onefile --name hello-single hello.py
.\dist\hello-single.exe

Puede distribuir dist\hello-single.exe por sí solo; el mensaje es el mismo. Al arrancar extrae archivos internos a una ubicación temporal, lo que puede aumentar el tiempo de inicio. Evalúe tamaño y velocidad en la aplicación real sin dar por hecho ventajas constantes.

No añada --windowed a este ejemplo de consola. Puede servir para interfaces gráficas sin consola, pero aplicarlo indiscriminadamente a programas con print() o input() dificulta entradas, salidas y diagnóstico. Investigue la causa en vez de convertir la ejecución como administrador o la desactivación de protecciones en soluciones predeterminadas.

Los ejemplos de carpeta y archivo único se construyeron en Windows con Python 3.12.14 y PyInstaller 6.22.3 y se verificó su salida. Son pruebas de consola en el mismo equipo, no de otro PC sin Python ni de una aplicación gráfica.

Incluir texto, imágenes y otros datos

No suponga que todos los archivos leídos por el código se recopilan automáticamente. Guarde message.txt en UTF-8 con la línea Hello from bundled data!. Cree junto a él hello_data.py con este código completo:

from pathlib import Path

message = Path(__file__).resolve().with_name("message.txt")
print(message.read_text(encoding="utf-8").strip())
Hello from bundled data!

El código fuente y el siguiente ejecutable deben mostrar el mismo mensaje. Una ruta basada en __file__ no depende de la carpeta actual del terminal y permite localizar archivos dentro del paquete.

.\.venv\Scripts\python.exe -m PyInstaller --onefile --name hello-data --add-data "message.txt:." hello_data.py
.\dist\hello-data.exe

--add-data "message.txt:." incorpora el archivo al nivel superior del paquete. El separador documentado actualmente es dos puntos; no mezcle ejemplos antiguos de separadores específicos por plataforma. Haga coincidir las rutas con las reglas de inclusión de datos para imágenes y configuración. Los cambios en datos extraídos de un EXE único no son almacenamiento persistente. Guarde ajustes y resultados del usuario en otra ubicación escribible.

Diagnosticar fallos y comprobar la distribución

  1. Si el EXE se cierra enseguida, ejecútelo desde PowerShell en lugar de hacer doble clic para leer el error. Compruebe primero que el código fuente funciona en el mismo entorno virtual.
  2. Si falta un módulo, revise su instalación y el método de importación. Las importaciones dinámicas pueden requerir opciones adicionales. Lea build\nombre\warn-nombre.txt, sin considerar fatal toda advertencia.
  3. Si faltan datos, compare el destino de --add-data y la ruta del código. Vuelva al formato de carpeta para inspeccionar archivos y acotar la causa.
  4. Pruebe las funciones en el sistema y arquitectura de destino. Incluya otro entorno sin Python, acceso a archivos, dependencias de programas externos y condiciones de redistribución de los paquetes.

Consulte la guía de resolución de problemas de PyInstaller. Distinga construcción de ejecución y registre código reproducible, versiones y mensajes de error para facilitar el diagnóstico.