Los paquetes en Python son una poderosa herramienta que permite la organización eficiente de módulos. Un paquete es esencialmente un directorio que contiene un archivo __init__.py y varios módulos o subpaquetes. Esta estructura organizacional no solo ayuda a mantener el código ordenado, sino que también facilita la reutilización de componentes de software.
¿Cuál es la diferencia entre un módulo y un paquete?
Módulo: Es un archivo único con extensión .py que contiene código de Python.
Paquete: Es una carpeta que reúne varios módulos o subpaquetes, con un archivo __init__.py que indica que se está trabajando con un paquete.
En resumen, mientras que un módulo es un solo archivo de Python, un paquete es una colección de módulos relacionados organizados de manera jerárquica.
¿Cómo crear un paquete en Visual Studio Code?
Crear un paquete en Python es un proceso sencillo que puede realizarse fácilmente en un entorno de desarrollo como Visual Studio Code.
Creación de la carpeta del paquete:
Primero, creamos una carpeta para el paquete. En el ejemplo, esta carpeta se llama e-commerce.
Incluir el archivo __init__.py:
Dentro de esta carpeta, agregamos un archivo __init__.py. Este archivo actúa como indicador de que la carpeta es un paquete.
Agregar módulos:
Añadimos los módulos necesarios dentro de la carpeta del paquete. En este caso, los módulos son inventario y ventas.
Desarrollar las funciones dentro de los módulos:
Por ejemplo, en el módulo inventario.py, se pueden definir funciones como add_product para agregar productos al inventario:
Uso de paquetes desde un archivo principal main.py:
Una vez definidos los paquetes y módulos, se puede crear un archivo main.py para importar y utilizar las funciones de estos paquetes.
from ecommerce.inventario import add_product, remove_product
from ecommerce.ventas import process_sale
add_product('Laptop',10)remove_product('Laptop')process_sale('Laptop',2)
Con estos pasos, se ha creado un paquete sencillo en Python, demostrando la facilidad de organización que los paquetes proporcionan.
¿Cómo funcionan los subpaquetes?
Los subpaquetes son estructuras que permiten aún más granularidad y organización dentro de un paquete. Funcionan de manera similar a los paquetes, pero están contenidos dentro del paquete principal.
Estructura:
Un subpaquete tiene su propia carpeta con archivos __init__.py y varios módulos.
Ejemplo de uso:
Se puede tener un subpaquete de inventario dentro del paquete e-commerce, que a su vez contiene un módulo llamado stock.
Reto:
El reto es crear y acceder a los subpaquetes desde un archivo principal, estableciendo la estructura completa necesaria.
Conocer y manejar paquetes y subpaquetes es esencial para cualquier desarrollador Python que desee desarrollar aplicaciones escalables y mantenibles. ¡Sigue practicando para perfeccionar tus habilidades en esta área!
Publicación y distribución de paquetes
Aunque este tema no se ha abordado con profundidad en el contenido proporcionado, es importante señalar que después de dominar la creación de paquetes, el siguiente paso natural es aprender a publicarlos para que la comunidad pueda beneficiarse de tu trabajo. En esta etapa, herramientas como PyPI (Python Package Index) se vuelven esenciales.
Continúa expandiendo tus conocimientos y habilidades con respecto a los paquetes para poder compartir tus desarrollos y colaborar con otros en la comunidad de Python.
La **gestión de paquetes** en Python permite organizar, reutilizar y distribuir módulos o grupos de módulos de manera eficiente. Los **paquetes** son carpetas con módulos (archivos .py) y un archivo especial \_\_init\_\_.py, que convierte la carpeta en un paquete reconocible por Python. Esta organización es clave para proyectos de gran tamaño, donde diferentes funcionalidades se agrupan en paquetes separados, manteniendo el código limpio y modular.
### ¿Qué es un Paquete?
Un paquete en Python es una colección de módulos organizados en una estructura de carpetas, donde cada módulo puede contener funciones, clases y variables relacionadas. Esta estructura modular facilita:
1. **Organización del código** en componentes lógicos.
2. **Reutilización y distribución** del código en otros proyectos.
3. **Escalabilidad** en proyectos complejos, separando funcionalidades en varios paquetes.
### Estructura Básica de un Paquete
Un paquete debe incluir un archivo \_\_init\_\_.py en su carpeta principal para que Python reconozca la carpeta como un paquete importable. Aunque \_\_init\_\_.py puede estar vacío, generalmente se utiliza para importar submódulos o funciones comunes.
Crea el archivo main.py fuera de la carpeta del paquete. Aquí puedes importar y usar las funciones definidas en mi\_paquete.
**Contenido de main.py:**
\# main.py
from mi\_paquete import sumar, restar, contar\_palabras, a\_mayusculas
print("Suma:", sumar(5,3))print("Resta:", restar(10,4))print("Número de palabras:", contar\_palabras("Este es un ejemplo"))print("Texto en mayúsculas:", a\_mayusculas("texto en minúsculas"))
### Ejecución del Ejemplo
Para ejecutar el ejemplo:
1. Asegúrate de estar en el directorio donde se encuentra main.py.
2. Ejecuta main.py con:
```bash
python main.py
```
La salida debería ser algo similar a:
Suma:8Resta:6Número de palabras:4Texto en mayúsculas:TEXTOENMINÚSCULAS
### Gestión de Paquetes con pip
Si deseas compartir o distribuir el paquete, puedes crear un archivo setup.py, que facilita la instalación del paquete mediante pip. Esto es útil para distribuir el paquete a otros usuarios o para subirlo a PyPI (Python Package Index).
**Ejemplo de setup.py:**
\# setup.py
from setuptools import setup, find\_packages
setup(  name='mi\_paquete',  version='0.1',  packages=find\_packages(),  description='Un paquete de ejemplo para operaciones matemáticas y de texto',  author='Tu Nombre',  author\_email='tu\_email@example.com',)
Para instalar el paquete en tu entorno local:
pip install.
### Resumen
1. **Estructura de Paquete**: Organiza el proyecto en carpetas y módulos con un archivo \_\_init\_\_.py.
2. **Modularidad y Reutilización**: Puedes reutilizar módulos y funciones en otros proyectos.
3. **Distribución**: Usa setup.py para facilitar la instalación y compartir el paquete.
Crear paquetes en Python es fundamental para desarrollar aplicaciones escalables, modulares y reutilizables, permitiendo que el código sea mantenible y fácil de distribuir.
Gracias por tu aporte
ni tocaron la estructura del init entonces no me queda claro para que o que hace ese file o como organiza la estructura dentro del directorio.
'__init__.py ' es un archivo que interpreta python para transformar un directorio en un módulo
En otras palabras, convierte una carpeta cualquiera en un modulo de python
el archivo __init__.py es un archivo especial para que el paquete sea reconocido como tal, aunque este ya no es necesario desde la versión 3.3 de Pythonn en adelante.
from ecommerce.inventory.stock import add_product, remove_product
from ecommerce.sales.orders import process_sale
add_product('PS5',4)remove_product('PS4')process_sale('PS5',1)```from ecommerce.inventory.stock import add\_product, remove\_productfrom ecommerce.sales.orders import process\_sale
add\_product('PS5',4)remove\_product('PS4')process\_sale('PS5',1)
Gestión de Entornos Virtuales
Para evitar conflictos entre dependencias de diferentes proyectos, es recomendable usar entornos virtuales. Puedes crear y activar un entorno virtual usando venv:
# Crear un entorno virtualpython -m venv mi_entorno
# Activar el entorno virtual# En Windowsmi_entorno\Scripts\activate
# En Unix o MacOSsource mi_entorno/bin/activate
Gracias por tu aporte
from ecommerce.inventory.stockimport add_product, remove_product
from ecommerce.sales.ordersimport process_sale
add_product("Laptop",2)remove_product("Laptop",2)process_sale("Laptop",2)
MUY BUEN APORTE
Para los que tenemos un ligero retraso mental, como creo el main.py afuera de ecommerce, ya que al querer crearlo queda dentro y no fuera, se que es una tarades pero si se queda uno con la duda.
OLVIDENLO!!!!!! Yo solito me respondi.
El archivo main.py es el punto de entrada principal de un paquete en Python. En este archivo, se importan y utilizan las funciones y módulos definidos en otros archivos dentro del paquete. En el contexto de tu curso, main.py permite gestionar las operaciones del inventario y las ventas, llamando a funciones como add_product, remove_product y process_sale. Así, main.py actúa como el controlador que coordina la interacción entre los distintos componentes del paquete.
El archivo __init__.py es crucial en Python porque indica que el directorio que lo contiene debe ser tratado como un paquete. Este archivo puede estar vacío o contener código de inicialización. Su nombre con guiones bajos es una convención de Python que permite que el intérprete reconozca el directorio como un módulo. Así, puedes importar funcionalidades de los módulos dentro de ese paquete. Esto es fundamental para organizar el código de manera estructurada y reutilizable en proyectos más grandes.
from ecommerce.productos.gestion import consultar_stock
from ecommerce.ventas.carrito import Carrito
def menu():
carro = Carrito()
while True:
print("\\n1. Ver Stock | 2. Comprar | 3. Salir")
op = input("Opción: ")
if op == "1": consultar_stock()
elif op == "2":
prod = input("Producto: ").lower()
cant = int(input("Cantidad: "))
carro.agregar(prod, cant)
elif op == "3": break
menu()
'''
}
Me emocioné un poco con la primera función porque quería que me quedara medianamente decente la parte de inventario simulando la base de datos, ya en la de orders me dio flojera y la simulé sin más con un print jajajaja
inventory =[]defadd_product(product_name, stock):"""
Agrega un producto a la lista de inventario.
Cada producto se representa como un diccionario:
{ "product": "Nombre", "stock": 10 }
Argumentos:
product_name (str): El nombre del producto.
stock (int): La cantidad disponible.
Retorna:
list: La lista de inventario actualizada.
"""# Creamos el diccionario que representa al producto# Un diccionario es ideal porque nos permite etiquetar los datos (clave: valor) product_entry ={"product": product_name,"stock": stock}# Agregamos el diccionario a nuestra lista de inventario inventory.append(product_entry)return inventory
if __name__ =="__main__":# Probamos la función agregando un par de productosprint("--- Agregando productos ---") add_product("Laptop",10) add_product("Mouse",25)# Imprimimos el inventario final formatado para que sea legibleprint("\nEstado del inventario:")for item in inventory:print(f"Producto: {item['product']} | Stock: {item['stock']}")defprocess_sale(order_name, quantity):print(f"Vent procesada: {quantity} unidades de {order_name}")from ecommerce.inventory.stock import add_product, inventory
from ecommerce.sales.orders import process_sale
add_product("Laptop",10)print(inventory)process_sale("Laptop",5)
from ecommerce.inventory.stock import add_product, remove_product
from ecommerce.sales.orders import process_sale
add_product("refrigeradora",7)remove_product("refrigeradora")process_sale("refrigeradora",3)
gente recuerden que cualquier duda adicional que tengan o que no salga en la clase tenemos un recuadro de texto debajo del video donde podemos preguntar y nos responde ADA
__init__ podría decirse que solo es una buena practica?
excelente todo pero el archivo que cree init__.py para que serviria?
El archivo __init__.py sirve para decirle a la carpeta que es un modulo y puede usarse para controlar qué funciones o módulos se exponen al importar el paquete.
El archivo __init__.py se utiliza para indicar que un directorio es un paquete de Python. Este archivo puede estar vacío, pero también puede contener código de inicialización que se ejecuta al importar el paquete. No es estrictamente necesario crearlo en Python 3.3 y versiones posteriores, ya que los directorios se consideran paquetes incluso sin él. Sin embargo, incluirlo es una buena práctica para mantener compatibilidad y claridad en el código.
Aquí mi aporte:
He creado un archivo JSON/inventario.json que contiene información de los productos. Se usará como una fuente de datos.
Dentro del subpaquete ecommerce/inventory el módulo "stock.py" se usa para realizar diversas funciones como "agregar_producto()", "eliminar_producto()", "incrementar_stock_producto()", "reducir_stock_producto()", "validar_stock()". Este módulo usa el archivo JSON/inventario.json y lo actualiza de acuerdo a las necesidades.
Dentro del subpaquete ecommerce/sale el módulo "orders.py" tiene la función "procesar_orden()" la que a su vez valida previamente el stock y de ser correcto, procesa la orden y reduce el stock, actualizando también el archivo JSON.
Finalmente el archivo "main.py" que invoca a los subpaquetes y módulos.
[{"id":"0001","name":"Laptop","price":1200.0,"quantity":4,"category":"Electronics","entry_date":"2024-01-05"},{"id":"0002","name":"Mouse","price":45.0,"quantity":165,"category":"Accessories","entry_date":"2024-02-10"},{"id":"0003","name":"Keyboard","price":70.0,"quantity":60,"category":"Accessories","entry_date":"2024-02-12"},{"id":"0004","name":"Monitor","price":320.0,"quantity":5,"category":"Electronics","entry_date":"2024-03-01"},{"id":"0005","name":"Headphones","price":150.0,"quantity":25,"category":"Audio","entry_date":"2024-03-15"},{"id":"0006","name":"Webcam","price":85.0,"quantity":40,"category":"Electronics","entry_date":"2024-03-20"},{"id":"0007","name":"Printer","price":200.0,"quantity":10,"category":"Office","entry_date":"2024-04-01"},{"id":"0008","name":"Tablet","price":400.0,"quantity":30,"category":"Electronics","entry_date":"2024-04-05"},{"id":"0009","name":"Smartphone","price":800.0,"quantity":20,"category":"Electronics","entry_date":"2024-04-10"},{"id":"0010","name":"External Hard Drive","price":100.0,"quantity":50,"category":"Storage","entry_date":"2024-05-01"},{"id":"0011","name":"Speaker","price":90.0,"quantity":35,"category":"Audio","entry_date":"2024-05-05"},{"id":"0012","name":"Microphone","price":110.0,"quantity":18,"category":"Audio","entry_date":"2024-05-10"},{"id":"0013","name":"Charger","price":25.0,"quantity":150,"category":"Accessories","entry_date":"2024-05-15"},{"id":"0014","name":"USB Cable","price":10.0,"quantity":200,"category":"Accessories","entry_date":"2024-05-20"},{"id":"0015","name":"Power Bank","price":60.0,"quantity":80,"category":"Accessories","entry_date":"2024-05-25"},{"id":"0016","name":"Router","price":150.0,"quantity":25,"category":"Networking","entry_date":"2024-06-01"},{"id":"0017","name":"Mouse Pad","price":20.0,"quantity":100,"category":"Accessories","entry_date":"2024-06-05"},{"id":"0018","name":"Laptop Stand","price":55.0,"quantity":45,"category":"Accessories","entry_date":"2024-06-10"},{"id":"0019","name":"Projector","price":55000,"quantity":20,"category":"Electronics","entry_date":"2024-06-15"},{"id":"0020","name":"Graphics Tablet","price":250.0,"quantity":12,"category":"Electronics","entry_date":"2024-06-20"}]
Módulo ecommerce/inventory/stock.py
import json
ruta_archivo ="JSON/inventario.json"def __get_inventory()-> list[dict]: # Leer el archivo JSON-->Simulamos una base de datos
withopen(ruta_archivo,"r")asfile: productos = json.load(file)return productos
def show_inventory(): productos =__get_inventory()for producto inproductos:print(producto)def validar_stock(product_name: str,quantity: int): # Leer el archivo JSON-->Simulamos una base de datos
withopen(ruta_archivo,"r")asfile: productos = json.load(file) # Validar la existencia del producto y stockn en el inventario
product =next((p for p in productos if p['name']==product_name and p['quantity']>= quantity),None)ifproduct:returnTrueelse:returnFalse
# agregar un nuevo producto al inventario
def add_product(product : dict): # Leer el archivo Json productos =__get_inventory() id_max =max([int(p['id'])for p in productos]) id_new =str(id_max+1).zfill(4) product['id']= id_new
productos.append(product) #Actualizar el archivo JSON con los nuevos valores
withopen(ruta_archivo, mode='w')asf: json.dump(productos, f, indent=4)print(f'Nuevo Producto: {product['name']} agregado con id {id_new} y {product['quantity']} unidades.')print(product)
#elimina un producto del inventario
def remove_product(product_name : str): # Leer el archivo Json productos =__get_inventory() product =next((p for p in productos if p['name']==product_name),None)ifproduct: productos.remove(product) #Actualizar el archivo JSON con los nuevos valores
withopen(ruta_archivo, mode='w')asf: json.dump(productos, f, indent=4)print(f'Producto {product_name} eliminado del inventario.')else:print(f'Producto {product_name} no encontrado en el inventario.')#Incrementar el stock de un producto del inventario
def increment_stock_product(product_name : str,stock: int): nuevo_stock =0 # Leer el archivo Json productos =__get_inventory() product =next((p for p in productos if p['name']==product_name),None)ifproduct: product['quantity']+= stock
nuevo_stock = product['quantity'] #Actualizar el archivo JSON con los nuevos valores
withopen(ruta_archivo, mode='w')asf: json.dump(productos, f, indent=4)print(f'Producto {product_name} ha incrementado su stock en {stock} unidades. Nuevo stock: {nuevo_stock}')else:print(f'Producto {product_name} no encontrado en el inventario.')#Reducir el stock de un producto del inventario
def reduce_stock_product(product_name : str,stock: int): nuevo_stock =0 # Leer el archivo Json productos =__get_inventory() product =next((p for p in productos if p['name']==product_name),None)ifproduct: product['quantity']-= stock
nuevo_stock = product['quantity'] #Actualizar el archivo JSON con los nuevos valores
withopen(ruta_archivo, mode='w')asf: json.dump(productos, f, indent=4)print(f'Producto {product_name} ha reducido su stock en {stock} unidades. Nuevo stock: {nuevo_stock}')else:print(f'Producto {product_name} no encontrado en el inventario.')
Módulo ecommerce/sales/orders.py
from ecommerce.inventory.stockimport validar_stock,reduce_stock_product
def procesar_orden(id_orden,product_name, quantity)-> bool:if(validar_stock(product_name,quantity)): #id_orden =str(random.randint(1,10)).zfill(5) #Autogenero un id de la orden
print(f'Orden: {id_orden} procesada y finalizada. Producto: {product_name} y cantidad: {quantity}')reduce_stock_product(product_name,quantity)returnTrueelse:print(f'No se ha procesado la Orden. No hay stock para: {product_name} y cantidad: {quantity}.')returnFalse
Archivo main.py
# estructura:# main.py# ecommerce/# ├── inventory/# ├── __init__.py# └── stock.py# ├── sales/# ├── __init__.py# └── orders.py# JSON/# └── inventario.json#Importa funciones de los modulos
from ecommerce.inventory.stockimport show_inventory,add_product,remove_product
from ecommerce.sales.ordersimport procesar_orden
def main(): #Leer inventario
show_inventory() #Agregar un nuevo producto al inventario
new_product ={"name":"Wireless Charger","price":75.00,"quantity":100,"category":"Accessories","entry_date":"2024-07-01",}add_product(new_product) #Procesar órdenes
# 1era orden
procesar_orden('001','Smartphone',5)
# 2da orden
procesar_orden('002','Speaker',10)
# 3era orden
procesar_orden('003','Router',30) #Eliminar un producto
remove_product('Wireless Charger')remove_product('Graphics Tablet') #Leer inventario
show_inventory()if __name__ =="__main__":main()```RESULTADO:
Visual Studio Code detecta llos cambios y ajusta la direccion para que puedas acceder a los paquetes.