Saltar a contenido

Importación de submódulos en Python

Python nos ofrece dos maneras distintas de importar módulos: podemos usar import por sí solo o combinarlo con from para tener un control más granular, concreto, sobre qué funciones específicas queremos utilizar y cómo queremos acceder a ellas.

Anteriormente, cuando utilizamos la instrucción import random en Python, lo que en realidad hicimos fue efectuar una importación integral del módulo.

¡Para recordar!

La palabra clave import por sí sola nos da acceso a todo el módulo, lo que significa que traemos a nuestro programa todas las funcionalidades disponibles en dicho módulo, no solo aquellas que planeamos utilizar.

Además, requiere que antepongamos el nombre del módulo cada vez que queremos usar una de sus funciones, como hicimos en nuestro ejemplo anterior al escribir random.choice().

Esta aproximación, aunque completa, tiene una implicación sintáctica importante: cada vez que queremos utilizar una función del módulo, debemos especificar su procedencia utilizando la notación punto: random.choice, random.randint, etc.

Imaginemos que estamos en una biblioteca donde random es un estante completo de libros. Al hacer import random, es como si trajéramos todo el estante a nuestra mesa de trabajo. Aunque solo necesitemos consultar un libro específico (digamos, el equivalente a la función choice), estamos cargando con todo el estante y, además, cada vez que queremos referirnos a ese libro, debemos especificar que viene de ese estante particular.

Importando un componente específico con from… import

Es aquí donde la sintaxis from módulo import función_específica se vuelve especialmente valiosa, ya que nos permite seleccionar exactamente qué componentes queremos importar, similar a tomar prestado solo un libro específico de una saga1 en lugar de cargar con la saga completa.

¡Para recordar!

Por ejemplo, si de toda la biblioteca matemática solo necesitamos la función de raíz cuadrada, podríamos escribir from math import sqrt en lugar de importar todo el módulo matemático, lo que no solo hace nuestro código más eficiente en términos de uso de memoria, sino que también lo hace más claro al indicar exactamente qué funcionalidades estamos utilizando en nuestro programa.

Cuando utilizamos from junto con import, como en from random import choice, estamos siendo más específicos. Es similar a arrancar una página específica del libro y tenerla directamente sobre nuestra mesa de trabajo. Esta sintaxis nos permite usar la función directamente por su nombre choice() sin necesidad de especificar el módulo cada vez.

Si retomamos el ejemplo del lanzamiento de moneda, podríamos importar solo la función choice del módulo random de la siguiente manera:

Programa completo
from random import choice

lanzamiento = choice(["cara", "cruz"])
print(lanzamiento)

En este caso, no necesitamos anteponer random a choice porque ya hemos importado la función específica que queremos utilizar.

¡Para recordar!

El uso de from… import carga la función en nuestro espacio de nombres local (o local namespace), lo que significa que podemos usarla directamente por su nombre sin tener que especificar el módulo cada vez, ya que dicha función ya está en nuestro vocabulario local, en el ámbito (scope) del archivo principal de trabajo.

Veamos la diferencia entre ambas aproximaciones:

Usando solo import
# Usando solo import
import random
lanzamiento = random.choice(["cara", "cruz"])
print(lanzamiento)
Usando from import
# Usando from import
from random import choice
lanzamiento = choice(["cara", "cruz"])
print(lanzamiento)

Importando múltiples componente específicos con from… import

También podemos importar múltiples funciones específicas de un módulo:

Importando múltiples funciones
# Importar varias funciones específicas
from random import choice, randint, shuffle

(El resto del código va aquí...)

Importando todos los componente con * y from… import

O incluso podemos importar todas las funciones de un módulo usando el asterisco (*), aunque esto generalmente no se recomienda hacerlo, ya que puede causar conflictos de nombres y hacer que sea más difícil rastrear de dónde provienen las funciones:

Importando todo el contenido del módulo
# Importar todo el contenido del módulo
from random import *  # No es una práctica recomendada

# El resto del código va aquí...

¿Cuándo usar cada método de importación?

La elección depende del contexto:

Usar solo import es preferible cuando:

  • Queremos hacer explícito de dónde viene cada función, mejorando la legibilidad del código
  • Nos aseguramos de que todo su contenido esté asociado o limitado al módulo importado
  • Necesitamos evitar conflictos o colisiones de nombres entre diferentes módulos, funciones o variables que se llamen igual
  • Estamos trabajando con un módulo del que usaremos muchas funciones diferentes

Usar from import es más apropiado cuando:

  • Vamos a utilizar una función específica muchas veces y queremos hacer el código más conciso
  • Estamos seguros de que los nombres de las funciones no entrarán en conflicto con otros en nuestro código
  • Queremos importar solo una pequeña parte de un módulo grande

Para los programadores principiantes, generalmente se recomienda comenzar con import solo, ya que hace más explícito el origen de cada función y ayuda a comprender mejor la estructura del código. A medida que se gana experiencia, se puede empezar a utilizar from import de manera más selectiva cuando tenga sentido para la organización del código.

¡Para recordar!

Python y otros lenguajes te permiten limitar los nombres de esas funciones y variables al archivo o módulo del que provienen al utilizar la palabra clave import.


Referencias:


  1. En un sentido moderno, una saga es una serie de historias, libros, películas o videojuegos que están conectados entre sí, generalmente por compartir personajes, un universo o una línea argumental.