Guía de creación, gestión y distribución de paquetes de Python | Explicación completa desde principiantes hasta la práctica

目次

1. Introducción

La importancia de los paquetes en Python

Los paquetes de Python son colecciones de múltiples módulos que facilitan la reutilización y gestión del código, siendo un mecanismo importante. Especialmente en proyectos a gran escala, al estructurar adecuadamente los paquetes, se mejora la legibilidad y mantenibilidad del código.

El ecosistema de Python ya cuenta con numerosos paquetes (bibliotecas) convenientes, pero al crear paquetes personalizados y aplicarlos a los proyectos, se puede lograr un desarrollo más flexible.

Propósito y resumen de este artículo

En este artículo, se explicará en detalle lo siguiente sobre los paquetes de Python.

  • Conceptos básicos y estructura de los paquetes
  • Método para crear paquetes personalizados
  • Método para importar paquetes
  • pip Gestión de paquetes con
  • Procedimiento para publicar en PyPI (Python Package Index)
  • Errores comunes y sus soluciones (FAQ)

Al leer esta guía, podrá aprender sistemáticamente sobre los paquetes de Python y utilizarlos en la práctica.

Público objetivo

Este artículo está dirigido a personas como las siguientes.

  • Personas que entienden la sintaxis básica de Python y tienen experiencia creando scripts simples o funciones
  • Personas que desean organizar proyectos de Python y escribir código reutilizable
  • Personas que desean crear paquetes personalizados y publicarlos en PyPI

Para estos lectores, este artículo está estructurado para profundizar la comprensión sobre los paquetes de Python y proporcionar información útil para la práctica.

2. ¿Qué es un paquete de Python?

Diferencia entre paquetes y módulos

En Python, para organizar el código de manera adecuada y facilitar su reutilización, existen los conceptos de «módulo» y «paquete».

  • Módulo (Module)
    Se refiere a un único script de Python (.py archivo). Por ejemplo, un archivo de Python como el siguiente se considera un módulo.
  # sample_module.py
  def greet():
      return "Hello, Python!"
  • Paquete (Package)
    Es un directorio que agrupa varios módulos y, por lo general, incluye un archivo __init__.py. Al utilizar un paquete, se puede gestionar varios módulos de manera organizada.
  mypackage/
  ├── __init__.py
  ├── module1.py
  ├── module2.py

Diferencia con las bibliotecas

El término «biblioteca» también se utiliza con frecuencia, pero se trata de un concepto más amplio que incluye paquetes y módulos.
Específicamente, una biblioteca es un conjunto de paquetes que proporciona un conjunto de herramientas para funciones específicas se puede considerar de esa manera.

TérminoDescripción
MóduloUn script de Python (.py archivo)
PaqueteEstructura de directorios que agrupa módulos
BibliotecaConjunto de software que incluye varios paquetes

Por ejemplo, requests y numpy son paquetes, pero bibliotecas como SciPy o Django combinan varios paquetes.

El rol de __init__.py

El directorio de un paquete requiere un archivo especial llamado __init__.py. La existencia de este archivo permite que Python reconozca ese directorio como un «paquete».

Lo básico de __init__.py

__init__.py puede estar vacío sin problemas, pero se puede definir configuraciones iniciales o funciones principales del paquete de la siguiente manera.

# mypackage/__init__.py
from .module1 import greet

def welcome():
    return "Welcome to mypackage!"

Con esta configuración, al importar mypackage desde el exterior del paquete, se puede utilizar directamente la función greet().

from mypackage import greet
print(greet())  # Hello, Python!

Paquete de espacio de nombres (Namespace Package)

Desde Python 3.3, se admiten «paquetes de espacio de nombres (Namespace Package)» que reconocen paquetes sin __init__.py. Sin embargo, por consideraciones de compatibilidad, es común colocar __init__.py.

Resumen

  • Módulo es un único archivo .py, mientras que un paquete es una estructura de directorios que contiene varios módulos.
  • Biblioteca es un conjunto de software que combina paquetes y módulos.
  • __init__.py es necesario para identificar un paquete y permite definir configuraciones iniciales o importaciones convenientes.
  • Desde Python 3.3, también son posibles paquetes sin __init__.py (paquetes de espacio de nombres).
年収訴求

3. Cómo crear un paquete de Python

Estructura de directorios básica de un paquete

Los paquetes de Python funcionan correctamente al seguir una estructura de directorios específica. A continuación se muestra un ejemplo de la estructura de directorios de un paquete simple.

mypackage/
├── __init__.py  # Archivo para identificar el paquete
├── module1.py   # Módulo 1
├── module2.py   # Módulo 2
└── subpackage/  # Subpaquete
    ├── __init__.py
    ├── submodule1.py
    └── submodule2.py

Roles de cada archivo

  • mypackage/ : Directorio raíz del paquete
  • __init__.py : Archivo que indica que esta carpeta es un paquete (opcional desde Python 3.3)
  • module1.pymodule2.py : Módulos dentro del paquete
  • subpackage/ : Subpaquete (contiene más módulos internamente)

__init__.py : Creación y roles

__init__.py identifica el paquete y define el procesamiento de inicialización al importarlo.

__init__.py simple

Crear un __init__.py vacío como se muestra a continuación ya permite que funcione como paquete.

# mypackage/__init__.py

Agregar configuración inicial del paquete a __init__.py

A continuación se muestra un ejemplo más práctico de __init__.py.

# mypackage/__init__.py
from .module1 import greet

def welcome():
    return "Welcome to mypackage!"

Con esta configuración, al importar el paquete, la función greet() estará disponible.

from mypackage import greet
print(greet())  # "Hello, Python!"

Creación de módulos y subpaquetes

Creación de un módulo (module1.py)

Cada módulo puede definir sus propias funciones o clases.

# mypackage/module1.py
def greet():
    return "Hello, Python!"

Creación de un subpaquete (subpackage/)

Crear un subpaquete permite dividir las funciones de manera más detallada.

mypackage/
└── subpackage/
    ├── __init__.py
    ├── submodule1.py
    └── submodule2.py

Definir funciones en el __init__.py del subpaquete facilita su importación.

# mypackage/subpackage/__init__.py
from .submodule1 import sub_function

def subpackage_greeting():
    return "Hello from subpackage!"

Verificación del funcionamiento del paquete

Para verificar el paquete creado, utilice el shell interactivo de Python.

  1. mypackage Moverse al directorio padre
   cd path/to/your/package
  1. Abrir el shell de Python
   python
  1. mypackage Importar e ejecutar funciones
   import mypackage
   print(mypackage.welcome())  # "Welcome to mypackage!"

Resumen

  • Los paquetes de Python se componen de directorios y __init__.py.
  • __init__.py se utiliza para la identificación e inicialización del paquete.
  • Usar módulos y subpaquetes facilita la organización del código.
  • Después de crear, verificar en el shell de Python para confirmar que funciona correctamente.

4. Método de importación de paquetes

Importación de módulos dentro de un paquete

Al usar paquetes de Python, normalmente se utiliza la sentencia import. Por ejemplo, supongamos que hay una estructura de paquete como la siguiente.

mypackage/
├── __init__.py
├── module1.py
├── module2.py
└── subpackage/
    ├── __init__.py
    ├── submodule1.py

Importación directa de módulos

Supongamos que en module1.py está definida la función greet().

# mypackage/module1.py
def greet():
    return "Hello from module1!"

Para utilizar esta función, se usa la sentencia import de la siguiente manera.

import mypackage.module1

print(mypackage.module1.greet())  # Hello from module1!

Importación usando la palabra clave from

Si se desea importar de manera más concisa, se puede usar la palabra clave from.

from mypackage.module1 import greet

print(greet())  # Hello from module1!

Diferencia entre importación relativa e importación absoluta

En Python, al importar módulos dentro de un paquete, hay dos métodos: importación relativa y importación absoluta.

Importación absoluta (Absolute Import)

Es el método que especifica la ruta desde el directorio raíz del paquete.

# mypackage/module2.py
from mypackage.module1 import greet

def call_greet():
    return greet()

La ventaja de este método es que tiene alta legibilidad y muestra claramente la estructura del paquete.

Importación relativa (Relative Import)

Importa otros módulos basándose en la posición del módulo actual. Se puede referir a otros módulos en el mismo paquete usando . (punto).

# mypackage/module2.py
from .module1 import greet

def call_greet():
    return greet()

En la importación relativa, se puede especificar el nivel de directorio padre según el número de ..

  • from .module1 import greet → Importa greet() desde module1.py en el mismo paquete
  • from ..subpackage.submodule1 import some_function → Importa some_function desde subpackage/submodule1.py en un nivel superior

Importación relativa vs Importación absoluta

TipoVentajasDesventajas
Importación absolutaAlta legibilidad y estructura del paquete claraPuede requerir la descripción de rutas largas
Importación relativaFácil movimiento de código y descripciones cortas posiblesPuede causar errores al ejecutarse desde fuera del paquete

La importación relativa puede generar un ImportError al ejecutar el script desde fuera del paquete. Por lo tanto, en proyectos grandes en particular, se recomienda usar importación absoluta.

Simplificación de la importación aprovechando __init__.py

Al definir funciones o clases específicas en __init__.py, se puede simplificar la importación del paquete.

# mypackage/__init__.py
from .module1 import greet

Con esta configuración, se puede importar la función de manera simple como se muestra a continuación.

from mypackage import greet

print(greet())  # Hello from module1!

Resumen

  • Los métodos de importación de módulos son de dos tipos: import y from ... import.
  • La importación absoluta tiene alta legibilidad con especificación explícita de rutas, pero puede requerir descripciones largas.
  • La importación relativa permite descripciones cortas, pero dependiendo del método de ejecución del script, puede causar ImportError.
  • Al aprovechar __init__.py, se puede simplificar la importación del paquete.

5. Gestión de paquetes de Python (uso de pip)

pip Instalación y desinstalación de paquetes

En Python, se pueden instalar fácilmente bibliotecas externas usando pip.
Se descargan del Python Package Index (PyPI) oficial y se agregan al entorno.

Instalación de paquetes

Al ejecutar el siguiente comando, se puede instalar el paquete especificado.

pip install package_name

Por ejemplo, al instalar la biblioteca requests:

pip install requests

Una vez completada la instalación, se puede usar importando import en un script de Python.

import requests

response = requests.get("https://example.com")
print(response.status_code)

Desinstalación de paquetes

Para eliminar un paquete que ya no se necesita, use pip uninstall.

pip uninstall package_name

Por ejemplo, al desinstalar requests:

pip uninstall requests

Al ejecutarlo, se pedirá confirmación de desinstalación, así que ingrese y para eliminar.

pip freeze y requirements.txt para la gestión de entornos

Para compartir la lista de paquetes usados en un proyecto, es común crear un archivo llamado requirements.txt.

Salida de la lista actual de paquetes

Para listar los paquetes instalados en el proyecto, use el siguiente comando.

pip freeze

Ejemplo de salida:

requests==2.26.0
numpy==1.21.2
pandas==1.3.3

Al guardar esta lista en requirements.txt, se puede reproducir fácilmente los mismos paquetes en otros entornos.

pip freeze > requirements.txt

Instalación masiva de paquetes desde requirements.txt

Al configurar un proyecto en otro entorno, se pueden instalar todos los paquetes desde requirements.txt.

pip install -r requirements.txt

Gestión de paquetes en entornos virtuales (uso de venv)

En Python, para gestionar entornos de paquetes diferentes por proyecto, es común usar entornos virtuales (venv).
Usar entornos virtuales permite desarrollar sin afectar la configuración de paquetes del sistema completo.

Creación de entorno virtual

Mueva al directorio del proyecto y cree el entorno virtual con el siguiente comando.

python -m venv myenv

Se crea un entorno virtual llamado myenv/, que incluye el entorno de ejecución de Python.

Activación del entorno virtual

Para usar el entorno virtual creado, ejecute el siguiente comando.

  • Windows (en caso de PowerShell)
  myenvScriptsActivate
  • Mac / Linux
  source myenv/bin/activate

Cuando se activa el entorno virtual, se agrega una indicación como (myenv) a la línea de comandos.

Gestión de paquetes dentro del entorno virtual

Dentro del entorno virtual, se pueden instalar paquetes usando pip como de costumbre.

pip install flask

Para finalizar el entorno virtual, ejecute el siguiente comando.

deactivate

Gestión de versiones de paquetes

Confirmación de versión de paquetes instalados

Para confirmar las versiones de los paquetes actualmente instalados, use el siguiente comando.

pip list

O, para confirmar detalles de un paquete específico, use pip show.

pip show package_name

Ejemplo:

pip show numpy

Ejemplo de salida:

Name: numpy
Version: 1.21.2
Summary: NumPy is the fundamental package for array computing with Python.

Actualización de paquetes a la versión más reciente

Para actualizar un paquete existente a la versión más reciente, ejecute el siguiente comando.

pip install --upgrade package_name

Por ejemplo, al actualizar requests a la versión más reciente:

pip install --upgrade requests

Además, para actualizar todos los paquetes de una vez, use el siguiente comando.

pip list --outdated | awk '{print $1}' | xargs pip install --upgrade

(Nota: awk y xargs se pueden usar en Linux / Mac)

Resumen

  • Instalar paquetes con pip install package_name y eliminar con pip uninstall package_name.
  • Usar pip freeze > requirements.txt facilita la gestión de dependencias del proyecto.
  • Usando entornos virtuales (venv), se pueden construir entornos independientes por proyecto.
  • Confirmar versiones de paquetes instalados con pip list y actualizar con pip install --upgrade.

6. Método de distribución de paquetes de Python

pyproject.toml utilizado para la configuración de paquetes

En Python, se recomienda usar pyproject.toml al crear y distribuir paquetes. Este archivo contiene metadatos del paquete y información sobre dependencias.

Configuración básica de pyproject.toml

Cree pyproject.toml en el directorio raíz del proyecto y descríbalo de la siguiente manera.

[build-system]
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "mypackage" version = "0.1.0" description = "My Python package" authors = [{ name = "Your Name", email = "your_email@example.com" }] license = { text = "MIT" } dependencies = ["requests", "numpy"]

Con esta configuración, la compilación y distribución del paquete se realizarán de manera fluida.

Creación de paquetes usando setuptools

Para convertir el paquete en un formato distribuible (sdist o wheel), use setuptools.

Preparación del paquete

Prepare una estructura de directorios como la siguiente.

mypackage/
├── mypackage/
│   ├── __init__.py
│   ├── module1.py
│   ├── module2.py
├── pyproject.toml
├── README.md
└── LICENSE
  • mypackage/ : Código real del paquete
  • pyproject.toml : Archivo de configuración del paquete
  • README.md : Descripción del paquete
  • LICENSE : Información de licencia

Compilación del paquete

Mueva al directorio raíz del proyecto en la terminal y ejecute el siguiente comando.

python -m build

Esto generará un archivo .tar.gz (distribución de fuente) y un archivo .whl (wheel) en el directorio dist/.

dist/
├── mypackage-0.1.0-py3-none-any.whl
├── mypackage-0.1.0.tar.gz

Subida a PyPI usando twine

Para publicar el paquete en PyPI, use twine.

Verificación de funcionamiento en TestPyPI

Se recomienda verificar el funcionamiento del paquete en TestPyPI antes de subirlo al entorno de producción.

Primero, instale twine.

pip install twine

A continuación, suba el paquete a TestPyPI.

python -m twine upload --repository testpypi dist/*

Para instalar el paquete desde TestPyPI, use el siguiente comando.

pip install --index-url https://test.pypi.org/simple/ mypackage

Subida a producción en PyPI

Una vez verificado el funcionamiento en TestPyPI, suba al entorno de producción, que es PyPI.

python -m twine upload dist/*

Después de la subida, puede buscar el paquete en el sitio oficial de PyPI (https://pypi.org/) para confirmar que se ha publicado.

Instalación de paquetes desde PyPI

El paquete publicado se puede instalar con el siguiente comando.

pip install mypackage

Resumen

  • Se recomienda usar pyproject.toml para gestionar la información del paquete.
  • Use python -m build para convertir a formatos distribuibles (sdist, whl).
  • Después de verificar el funcionamiento en TestPyPI usando twine, suba a PyPI.
  • El paquete publicado se puede instalar con pip install.

7. Preguntas frecuentes (FAQ)

__init__.py ¿es estrictamente necesario?

Q: ¿Es __init__.py obligatorio?
A: A partir de Python 3.3, se introdujeron los «paquetes de espacio de nombres», que se reconocen como paquetes incluso sin __init__.py.
Sin embargo, en muchos proyectos, es común crear explícitamente __init__.py.

# mypackage/__init__.py

Al agregar este archivo, se puede describir el procesamiento de inicialización del paquete y simplificar las importaciones.

¿Cuál es la diferencia entre importaciones relativas e importaciones absolutas?

Q: ¿Cuál es la diferencia entre importaciones relativas e importaciones absolutas?
A: En Python, hay dos tipos de métodos de importación entre módulos: importación absoluta e importación relativa.

  • Importación absoluta
  from mypackage.module1 import greet
  • Especifica la ruta desde el directorio raíz, por lo que la estructura del paquete es fácil de entender
  • Alta legibilidad y menos propenso a errores
  • Importación relativa
  from .module1 import greet
  • Utiliza . (punto) para referenciar módulos dentro del mismo paquete
  • Al ejecutarse desde fuera del paquete, puede producirse un ImportError

¿Hay reglas de nomenclatura para paquetes?

Q: ¿Hay reglas para nombrar paquetes o módulos en Python?
A: PEP8 (la guía de estilo oficial de Python) recomienda las siguientes reglas de nomenclatura.

  • Nombre del paqueteUtilizar solo palabras en minúsculas
  mypackage, utilities, datahandler
  • Nombre del móduloUtilizar palabras cortas y claras en minúsculas
  module1, parser, reader

¿Cuál es el rol de requirements.txt?

Q: ¿Para qué se utiliza requirements.txt?
A: requirements.txt se utiliza para describir la lista de paquetes utilizados en el proyecto y mantener la reproducibilidad del entorno.

Para crearlo, ejecute el siguiente comando.

pip freeze > requirements.txt

Para instalar los mismos paquetes en otro entorno, ejecute el siguiente comando.

pip install -r requirements.txt

¿Por qué ocurre ModuleNotFoundError o ImportError?

Q: Explique las causas y soluciones para ModuleNotFoundError o ImportError.
A: Estos errores ocurren cuando Python no puede encontrar el módulo o paquete de manera adecuada.

ErrorCausaSolución
ModuleNotFoundErrorEl módulo no está instaladopip install package_name ejecutar
ImportErrorLa ruta de importación es incorrectaProbar importación absoluta

Solución para ModuleNotFoundError

  1. Verificar si el paquete está instalado
   pip list | grep package_name
  1. Si no está instalado, agregarlo con pip install
   pip install package_name

Solución para ImportError

  1. Probar importación absoluta
   from mypackage.module1 import greet
  1. Verificar el directorio de ejecución de Python
   import sys
   print(sys.path)

Después de subir a PyPI, ¿por qué no se puede pip install?

Q: Subí el paquete a PyPI, pero no se puede pip install. ¿Qué debo hacer?
A: Verifique los siguientes puntos.

  1. Verificar si la subida fue exitosa
   twine check dist/*
  1. Especificar el nombre correcto del paquete
   pip install mypackage
  1. Esperar la reflexión en PyPI
  • Después de la subida, puede tomar varios minutos para que se refleje en PyPI.
  1. En caso de haber subido a TestPyPI
  • En lugar de pip install, especificar --index-url
   pip install --index-url https://test.pypi.org/simple/ mypackage

Resumen

  • __init__.py no es obligatorio a partir de Python 3.3, pero es común agregarlo.
  • La importación absoluta se recomienda porque tiene alta legibilidad y menos errores.
  • Al utilizar requirements.txt, se puede gestionar fácilmente las dependencias de paquetes.
  • ModuleNotFoundError o ImportError se pueden resolver verificando el estado de instalación del paquete y la ruta de importación.

8. Resumen

Conceptos básicos de paquetes de Python

  • Módulo es un archivo único .py, paquete es un directorio que agrupa múltiples módulos.
  • Biblioteca es una colección de software que agrupa múltiples paquetes o módulos.
  • __init__.py es útil para identificar el paquete y simplificar las importaciones.

Métodos para crear paquetes de Python

  • Crear el directorio mypackage/ y agregar __init__.py para que sea reconocido como paquete.
  • Dividir los módulos de manera apropiada y diseñar código fácil de reutilizar.
  • Usar importación absoluta hace que las referencias a módulos dentro del paquete sean claras.

Métodos para gestionar paquetes

  • Instalar paquetes con pip install package_name, eliminar con pip uninstall package_name.
  • Usar pip freeze > requirements.txt facilita la reproducción del entorno del proyecto.
  • Crear un entorno virtual con python -m venv myenv permite construir entornos independientes por proyecto.

Distribución de paquetes

  • Gestionar metadatos del paquete usando pyproject.toml y construir en formato estándar.
  • Construir el paquete en el directorio dist/ usando python -m build.
  • Usar twine para verificar el funcionamiento en TestPyPI, y si no hay problemas, subir a PyPI.
  • Los paquetes publicados se pueden instalar fácilmente con pip install mypackage.

Errores comunes y soluciones

  • Para ModuleNotFoundError, verificar la instalación del paquete o la configuración de sys.path.
  • Para ImportError, probar importación absoluta en lugar de relativa.
  • Verificar versiones más recientes de paquetes con pip list --outdated y actualizar según sea necesario.

Mejores prácticas para la gestión de paquetes de Python

  1. Seguir las reglas de nomenclatura de paquetes
  • Usar nombres simples en minúsculas y considerar la legibilidad.
  1. Aprovechar los entornos virtuales (venv)
  • Se recomienda el desarrollo sin depender del entorno global.
  1. Gestionar siempre requirements.txt
  • Prevenir problemas en el desarrollo en equipo o en el despliegue.
  1. Verificar el funcionamiento en TestPyPI antes de publicar en PyPI
  • Prevenir errores de antemano y garantizar la calidad.

Resumen y aprendizaje futuro

Al entender los paquetes de Python y gestionarlos y distribuirlos adecuadamente, se puede lograr un desarrollo eficiente.
En particular, al adoptar un diseño que considere la reutilización de paquetes y un estilo de desarrollo que utilice entornos virtuales, se pueden construir proyectos de Python más robustos.

En el futuro, al aprender sobre temas como los siguientes, se puede profundizar la comprensión.

  • Desarrollo avanzado de paquetes (agregar scripts personalizados, introducir extensiones C)
  • Despliegue automático de paquetes utilizando CI/CD
  • Construcción de entornos combinados con Docker

Espero que este artículo sea de ayuda para utilizar efectivamente los paquetes de Python.
¡Gracias por leer hasta el final!

 

RUNTEQ(ランテック)|超実戦型エンジニア育成スクール