El sistema de importación (import)

El sistema de importación (import)

Python incluye un sistema de importación que permite:

  1. organizar códigos grandes en pequeñas porciones reutilizables;
  2. compartir tu código con otras personas e, inversamente, usar el código de otras personas.

Los conceptos principales del sistema de importación son los de módulo y paquete. Un módulo es un archivo de Python (por lo general con extensión .py, en ocasiones .pyd si se trata de un módulo compilado). Un paquete es una carpeta que en su interior contiene módulos u otros paquetes. A pesar de estas definiciones, a menudo los pythonistas usan los términos módulo y paquetes indistintamente, y realmente no hay mucho problema con eso. En término generales, cualquier cosa que pueda importarse (que ahora veremos de qué se trata) es un módulo. Usando las palabras reservadas from e import que provee el sistema, podemos utilizar variables, funciones, clases, excepciones y cualquier otro objeto que estén dentro de un módulo.

Veamos un ejemplo. Creemos dos archivos dentro de un mismo directorio con los nombres principal.py y mimodulo.py. Dentro de este último pondremos algunas funciones y variables:

# mimodulo.py
pi = 3.141592

def sumar(a, b):
    return a + b

def es_par(n):
    return n % 2 == 0

Si queremos usar algún objeto de este archivo desde nuestro principal.py, debemos importarlo vía la palabra reservada import y luego hacer uso de alguno de los objetos prefijando el nombre del módulo y un punto.

# principal.py
import mimodulo

resultado = mimodulo.sumar(7, 5)
print(resultado)
print(mimodulo.pi)

(Todos los import deben ir siempre, por convención, al inicio del archivo).

Cuando importamos un módulo, le indicamos a Python que queremos hacer uso de algún objeto dentro del mismo. En este caso, estamos usando la función sumar() y la variable pi. No hemos utilizado es_par(), pero no hay inconveniente. No es necesario usar todos los objetos de un módulo. Es común importar un módulo y solo usar uno o unos pocos objetos. Nótese que al indicar import mimodulo, no especificamos la extensión del archivo: el mimodulo podría ser un archivo mimodulo.py o mimodulo.pyd; Python importará el primero que encuentre.

El primer lugar donde buscará Python cuando le indicamos que debe importar un módulo es en la carpeta local o el directorio actual de trabajo (current working directory). El directorio actual de trabajo es la ubicación desde la cual un programa es ejecutado. Por ejemplo, si ejecutamos un archivo de Python desde la terminal, la ubicación donde esté la terminal al momento de ejecutar el archivo es el directorio actual de trabajo. Si ejecutamos un archivo desde un editor de código (como Geany, Visual Studio Code o PyCharm), el directorio actual de trabajo por lo general es la misma carpeta donde se encuentra el archivo en cuestión. (Para más información sobre el directorio actual de trabajo, véase La línea de comandos (o terminal) para pythonistas).

Si Python no encuentra el módulo en el directorio actual de trabajo, buscará en las carpetas Lib y Lib/site-packages, que se encuentran en el directorio de instalación de Python. De modo que cualquier módulo que se encuentre dentro de alguna de esas dos carpetas podrá ser importado desde cualquier ubicación. Si revisamos la carpeta Lib, encontraremos ahí ya gran cantidad de módulos y paquetes:

Módulos y paquetes de la librería estándar

La librería o biblioteca estándar es un conjunto de módulos y paquetes que se incluyen con cada instalación de Python y proveen soluciones para problemas comunes (y otros no tanto). Por ejemplo, el módulo estándar statistics contiene una función mean() para calcular el promedio de una lista de números:

>>> import statistics
>>> statistics.mean([1, 3, 7, 10])
5.25

En la carpeta Lib/site-packages se almacenan los módulos y paquetes desarrollados por la comunidad (listados en pypi.org), los cuales podemos instalar vía pip, que es la herramienta oficial del lenguaje para gestionar paquetes de terceros.

Formas de importar un módulo

Acabamos de ver cómo importar un módulo usando la palabra reservada import. Una sintaxis alternativa es la siguiente:

# principal.py
from mimodulo import sumar, pi

resultado = sumar(7, 5)
print(resultado)
print(pi)

Al usar la forma from ... import ..., le indicamos a Python específicamente cuáles objetos queremos importar de un módulo en particular. Luego, los objetos importados se incorporan a nuestro archivo como cualquier otro objeto definido dentro de él. Por esta razón, no es necesario (ni posible) usar el prefijo mimodulo. con este método.

Es importante saber que no hay diferencia de rendimiento entre este método y el anterior (import). Cuando usamos la sintaxis import mimodulo, simplemente le indicamos a Python que en algún momento haremos uso de algún objeto dentro de mimodulo; luego los objetos se importarán en efecto cuando sean utilizados. ¿Cuál de las dos sintaxis conviene utilizar, entonces? Depende de lo que se esté importando. En la mayoría de los casos es indiferente, y podemos elegir la sintaxis que nos resulte más cómoda. Pero en ciertas ocasiones una sintaxis tiene mejor legibilidad que otra. Si tenemos una línea de estas características:

import twisted.python.threadpool

tp = twisted.python.threadpool.Threadpool()

Para evitar tener que indicar toda la serie de módulos y paquetes (twisted.python.threadpool) como prefijo a la clase Threadpool, seguramente sea más sencillo y cómodo decir:

from twisted.python.threadpool import Threadpool

tp = Threadpool()

A veces, en cambio, usar el nombre del módulo como prefijo es muy esclarecedor, por lo cual conviene usar import. Por ejemplo, la función choice() («elegir») dentro del módulo estándar random («aleatorio»), selecciona un elemento aleatoriamente de la lista que pasamos como argumento. Si optamos por from random import choice, usaríamos la función de esta manera:

print(choice([1, 2, 3, 4, 5]))

Al ver esta línea de código, no sabemos con qué criterio choice() selecciona un elemento. En cambio, esto es bien claro:

print(random.choice([1, 2, 3, 4, 5]))

Cuando nos enfrentamos a un caso donde ninguna sintaxis tiene evidentemente un beneficio sobre la otra (en cuanto legibilidad), lo mejor es seguir la convención que encontremos en los ejemplos de la documentación oficial del módulo con el que estemos trabajando.



Deja una respuesta