Módulos y Paquetes

Hasta ahora hemos estado escribiendo código desde la terminal interactiva de Python, pero para proyectos siempre necesitamos algo que perdure, para esto estan los scripts de python, simples archivos de texto que en su interior tienen código que puede ser interpretado por Python.

A estas alturas estoy seguro que ya sabes de esto, pero también tendrás duda sobre como organizar tus proyectos. Ya hemos estado escribiendo algo de código, hemos hecho cosas sencillas porque la verdad estamos empezando, así que hemos hecho un scriptcito por aquí, otro por allá, pero empezamos a notar que cada vez nuestros scripts son mas grandes, los archivos son mas grandes y es mas tedioso organizar el código en un solo archivo.

Para eso existen los Módulos, básicamente los módulos son scripts de Python pero pueden ser importados por otros scripts, de forma que la funcionalidad pueda ser ocupada por este otro, es decir, pueda acceder a sus funciones y propiedades.

Entonces, un script de Python puede “importar” el contenido de otro?. Así es; y la forma de hacerlo es con la palabra reservada import

Supongamos que tenemos 2 scripts, uno que se llama main.py y otro que le pondremos modelos.py, en la primera definimos las bases de nuestro programa, y en el segundo definimos un par de clases que nos representan un objeto físico, digamos, animales.

Entonces, queremos que el contenido de modelos.pyesté disponible en main.py que es el que realizará la ejecución del programa. Para poder lograr esto tenemos que escribir en alguna parte de main.py el import , esto se debe hacer antes de intentar llamar alguna propiedad o función de modelos.pyya que si no lo hacemos así para Python el objeto no estará definido y nos lanzara un bonito error.

Entonces, en main.py tendremos que agregar el import , lo mejor es hacerlo al principio del archivo, para que así podamos ver todos los imports,

import modelos

Con esto todo lo que viene de modelos.py estará accesible en main . Y que sucede si modelos.py define una función que también main tiene definida?.

Bueno recordemos que Python usa espacios de nombres, por lo tanto, aunque hemos importado la funcionalidad de modelos, existe una forma particular para referirnos a su contenido. De acuerdo a como lo hemos importado en el ejemplo, tendremos que anteponer modelos. a cada propiedad que queramos llamar, es decir, que si tenemos la clase  Perro tendríamos que llamarlo así:

pug = modelos.Perro(raza="pug")

De esta forma evitamos sobreescribir las funciones, clases y propiedades definidas en el modelo actual.

Existe otra forma de usar el import de forma que obtengamos solo lo que nos interesa y no todo el módulo, digamos que en realidad nos interesa solamente la clase Perro, pero no vamos a ocupar Gato, Vaca ni alguna otra, entonces podremos importarlo así:

from modelos import Perro

Ahora, hemos importado Perro  a main , y en el espacio de nombres ahora existe Perro, como no hemos importado todo el módulo, no será necesario llamarle por modelos.Perro , solo tendremos que llamar la clase.

OJO: Aquí tendremos que tener cuidado de no sobreescribír alguna clase, puesto que la estamos agregando al espacio de nombres local. Podemos, entonces, cambiarle el nombre con el que lo estamos importando para evitar sobreescribir, para esto hemos de escribir al final as nuevonombre

from modelos import Perro as Dog

Ahora en el espacio de nombres existe Dog aunque es una referencia a Perro y tendremos que usarle así:

pug = Dog(raza="pug")

Importando varias cosas al mismo tiempo

La forma mas simple, conociendo el from modulo import X  seria hacerlo de esta forma:

from modulo import X
from modulo import Y
from modulo import Z

Sin embargo hay una forma mucho mas fácil y que requiere menos texto.

from modulo import X, Y, Z

Separamos el nombre de la clase o propiedad que queramos importar por una comma, fácil no?. Aquí también podremos usar el as W después del import.

Paquetes

Si los módulos son otros archivos de Python que nos sirven para organizar el código, entonces, los paquetes son directorios que nos ayudan a organizar estos módulos!

Gracias a los paquetes podemos organizar nuestro árbol de código de la forma que nos sea mas conveniente.

Como podemos ver en la imagen, sustes un paquete, dentro del cual hay otro paquete llamado views, y en cada uno de ellos hay varios archivos .py. Pero hay algo que podemos ver en común, cada directorio que es un paquete tiene un archivo llamado __init__.py

__init__.py

Podríamos decir que este archivo es el inicializador del paquete, a mi me gusta mas verlo como una representación pythonica del paquete, recordemos que el paquete es en si un directorio, pero un directorio no es un script de Python.

Este archivo permite definir algo en el paquete y se ejecutará cada vez que se importe el paquete, tal como sucede con los módulos.

Este archivo puede estar vacío, puede no tener nada, solo es necesario que esté presente si queremos que un directorio funcione como un paquete.

Y como importamos paquetes?

Pues de la misma forma que importamos módulos, import , solo que en este caso, cada nivel será un paquete o módulo separado por puntos.

import paquete.modulo.clase

Que también lo podríamos importar así:

from paquete.modulo import clase

Como ya lo habíamos mencionado antes, dependiendo de la forma en que lo importemos será como lo hemos de llamar (a = paquete.modulo.clase() o a = clase() ).

Así como con los módulos, podemos importar todos los módulos de un paquete o solo los que necesitamos.

from paquete import modulo
from paquete.modulo import clase
from paquete.otromodulo import *

Sencillo no?.

Notas finales

Algo que debemos tener en cuenta es que import evaluará el módulo que se esté importando, Python es un lenguaje de protocolo, por lo tanto ejecutará las funciones necesarias de acuerdo a las instrucciones en el script.

Si queremos crear un módulo que pretendemos sea importado por otro módulo, debemos evitar ejecutar código de forma automática, supongamos el siguiente script:

#!/usr/bin/env python

def suma(primero, segundo):
    """ Suma dos numeros """
    return primero + segundo

#Probando la función
print (suma(1, 2))

Este scripcito los podemos mandar llamar desde la terminal y siempre nos dará un texto:

python operaciones.py
3

Si este módulo lo importamos en otro script, siempre veremos impreso el numero “3”, puesto que la llamada a la función suma se ejecuta cada vez que es importado.

Loading

You must be logged in to take the quiz.