Vimos en conceptos anteriores que podemos dividir una aplicación en varios módulos y luego importarlos.
Recordemos que un módulo es un archivo con extensión 'py' y contiene en su interior funciones, clases, definición de variables etc.
Veremos ahora que un paquete en Python agrupa un conjunto de módulos relacionados y se los localiza en un directorio.
Veremos con un sencillo problema como creamos un paquete en Python.
Desarrollar una aplicación visual que muestre dos botones. Al presionar el primero mostrar otra ventana para el login, y al presionar el segundo mostrar una ventana de mensajes.
Crear un paquete llamado 'formularios' que contenga en su interior dos módulos llamados 'login.py' y 'mensaje.py'.
La aplicación principal llamarla 'principal.py'
Debemos crear una carpeta llamada 'formularios' y en su interior tres archivos: 'login.py', 'mensaje.py' y '__init__.py'.
El archivo '__init__.py' generalmente se encuentra vacío y tiene por objetivo indicar al intérprete de Python que dicha carpeta es un paquete.
Es decir que debemos tener los siguientes archivos y carpeta en nuestra aplicación:
import tkinter as tk from tkinter import ttk class Aplicacion: def __init__(self): self.ventana1=tk.Tk() self.labelframe1=ttk.LabelFrame(self.ventana1, text="Login:") self.labelframe1.grid(column=0, row=0, padx=5, pady=10) self.login() def login(self): self.label1=ttk.Label(self.labelframe1, text="Nombre de usuario:") self.label1.grid(column=0, row=0, padx=4, pady=4) self.entry1=ttk.Entry(self.labelframe1) self.entry1.grid(column=1, row=0, padx=4, pady=4) self.label2=ttk.Label(self.labelframe1, text="Ingrese clave:") self.label2.grid(column=0, row=1, padx=4, pady=4) self.entry2=ttk.Entry(self.labelframe1, show="*") self.entry2.grid(column=1, row=1, padx=4, pady=4) self.boton1=ttk.Button(self.labelframe1, text="Ingresar",command=self.ingresar) self.boton1.grid(column=1, row=2, padx=4, pady=4) def ingresar(self): self.ventana1.destroy() def mostrar(): aplicacion1=Aplicacion()
from tkinter import messagebox as mb def mostrar(mensaje): mb.showerror("Cuidado",mensaje)
Recordar de crear el archivo '__init__.py' en la carpeta 'formularios' y sin contenido (luego veremos que podemos disponer código en su interior que se ejecutará cuando importemos algún módulo del paquete)
Por otro lado creamos en la carpeta superior el script que contendrá la aplicación principal de nuestro programa que lo llamaremos 'principal.py'
import tkinter as tk from tkinter import ttk import formularios.login import formularios.mensaje class Aplicacion: def __init__(self): self.ventana1=tk.Tk() self.ventana1.title("Hola Mundo") self.boton1=ttk.Button(self.ventana1, text="Mostrar Mensaje", command=self.mostrar_mensaje) self.boton1.grid(column=0, row=0) self.boton2=ttk.Button(self.ventana1, text="Mostrar formulario de login", command=self.mostrar_login) self.boton2.grid(column=0, row=1) self.ventana1.mainloop() def mostrar_mensaje(self): formularios.mensaje.mostrar("Es una prueba de acceder a módulos de un paquete") def mostrar_login(self): formularios.login.mostrar() aplicacion1=Aplicacion()
Si ejecutamos la aplicación desde el script 'principal.py' tenemos como resultado en pantalla al presionar el botón "Mostrar formulario de login":
Como vemos la sintaxis para importar un módulo contenido en un paquete debemos anteceder al nombre del módulo el nombre del paquete:
import formularios.login import formularios.mensaje
Luego podemos acceder al módulo respectivo indicando primero el nombre del paquete, seguidamente el nombre del módulo y finalmente el nombre de la función:
formularios.login.mostrar()
De forma similar llamamos a la función 'mostrar' del módulo 'mensaje' contenido en el paquete 'formularios':
formularios.mensaje.mostrar("Es una prueba de acceder a módulos de un paquete")
Recordemos que podemos crear un alias cuando importamos un módulo con el fin de escribir menos cada vez que lo accedemos:
import tkinter as tk from tkinter import ttk import formularios.login as formlogin import formularios.mensaje as formmensaje class Aplicacion: def __init__(self): self.ventana1=tk.Tk() self.ventana1.title("Hola Mundo") self.boton1=ttk.Button(self.ventana1, text="Mostrar Mensaje", command=self.mostrar_mensaje) self.boton1.grid(column=0, row=0) self.boton2=ttk.Button(self.ventana1, text="Mostrar formulario de login", command=self.mostrar_login) self.boton2.grid(column=0, row=1) self.ventana1.mainloop() def mostrar_mensaje(self): formmensaje.mostrar("Es una prueba de acceder a módulos de un paquete") def mostrar_login(self): formlogin.mostrar() aplicacion1=Aplicacion()
Como vemos llamamos a la función mostrar del módulo 'login' directamente antecediendo el nombre del alias creado:
formlogin.mostrar()
También podemos hacer uso de la sintaxis del 'from' para importar módulos de un determinado paquete:
import tkinter as tk from tkinter import ttk from formularios import login from formularios import mensaje class Aplicacion: def __init__(self): self.ventana1=tk.Tk() self.ventana1.title("Hola Mundo") self.boton1=ttk.Button(self.ventana1, text="Mostrar Mensaje", command=self.mostrar_mensaje) self.boton1.grid(column=0, row=0) self.boton2=ttk.Button(self.ventana1, text="Mostrar formulario de login", command=self.mostrar_login) self.boton2.grid(column=0, row=1) self.ventana1.mainloop() def mostrar_mensaje(self): mensaje.mostrar("Es una prueba de acceder a módulos de un paquete") def mostrar_login(self): login.mostrar() aplicacion1=Aplicacion()
Un paquete en Python tiene en su interior módulos, pero puede tener otros subpaquetes que se deben crear en forma similar al paquete padre. También el subpaquete además de los módulos debe tener el archivo '__init__.py'.
Cuando importamos un subpaquete debemos indicar el nombre de la carpeta del paquete principal, luego el nombre de la carpeta del subpaquete y finalmente el nombre del módulo:
import formularios.modales.login import formularios.modales.mensaje import formularios.nomodales.ayuda
El nivel de subcarpetas dependerá de la complejidad de la aplicación que estemos implementando.