Mientras aprendes a programar y lees algunos recursos te habrás encontrado con esta palabra 'abstracción' que simplemente significa reducir y reutilizar el código tanto como sea posible.

Las funciones y los módulos facilitan la abstracción. Las funciones se crean cuando se quiere hacer algo repetidamente dentro de un archivo.

Los módulos entran en escena cuando se quiere reutilizar un grupo de funciones en diferentes archivos fuente. Los módulos también son útiles para estructurar bien el programa.

  • Uso de bibliotecas estándar y otros módulos de terceros.
  • Estructuración del programa.

Uso de bibliotecas estándar

Ejemplo: Puedes leer en detalle los métodos/funciones de todas las bibliotecas estándar en los Docs oficiales de Python.

import time
for i in range(100):
    time.sleep(1)   # Espera 1 segundo y luego ejecuta el siguiente comando
    print(str(i) + ' segundo ha pasado.')  # imprime el número de segundos transcurridos desde el inicio del programa
Módulo time

Corre el código

# Para calcular el tiempo de ejecución de una parte del programa
import time
start = time.time()
# Código aqui
end = time.time()
print('Tiempo de ejecución:' , end-start)
Módulo time
:rocket:

Corre el código

# Usando módulo math
import math
print(math.sqrt(100))   # Imprime 10
Módulo math
:rocket:

Corre código

Uso de módulos de terceros

Los módulos de terceros no vienen empaquetados con Python, sino que tenemos que instalarlos externamente usando gestores de paquetes como pip y easy install

# Para crear requsitos http
import requests
rq = requests.get(url_objetivo)
print(rq.status_code)
Módulo requests

Más información sobre el módulo python-requests aquí

Para estructurar los programas

Queremos hacer un programa que tenga varias funciones relacionadas con los números primos. Así que vamos a empezar. Definiremos todas las funciones en funciones_primos.py

# funciones_primos.py
from math import ceil, sqrt

def esPrimo(a):
    if a == 2:
        return True
    elif a % 2 == 0:
        return False
    else:
        for i in range(3,ceil(sqrt(a)) + 1,2):
            if a % i == 0:
                return False
        return True

def imprimir_n_primos(a):
    i = 0
    m = 2
    while True:
        if isPrime(m) ==True:
            print(m)
            i += 1
        m += 1
        if i == a:
            break
Módulo funciones_primos

Ahora, queremos usar las funciones que acabamos de crear en funciones_primos.py, así que creamos un nuevo archivo playground.py para usar esas funciones.

Tenga en cuenta que este programa es demasiado simple para hacer dos archivos separados, es sólo para demostrar. Pero cuando hay grandes programas complejos, hacer diferentes archivos es realmente útil.

# playground.py
import funciones_primos
print(funciones_primos.esPrimo(29)) # retorna True
Función principal

Clasificación de importaciones

Una buena práctica es clasificar los módulos de import en tres grupos: importaciones estándar de la biblioteca, importaciones de terceros relacionadas e importaciones locales. Dentro de cada grupo es sensato ordenar alfabéticamente por el nombre del módulo. Puedes encontrar más información en PEP8.

Una de las cosas más importantes para el lenguaje Python es la legibilidad y los módulos ordenados alfabéticamente son más rápidos de leer y buscar. También es más fácil verificar que algo es importado y evitar importaciones duplicadas.

From X import Y: un ejemplo

A continuación un ejemplo del problema:

>>> from math import ceil, sqrt
>>> # Aquí sería
>>> sqrt(36)
<<< 6
from math import ceil, sqrt
:rocket:

Corre el código

O podemos usar este en su lugar:

>>> import math
>>> # Aquí sería
>>> math.sqrt(36)
<<< 6
import math
:rocket:

Corre el código

Entonces nuestro código se vería como math.sqrt(x) en lugar de sqrt(x). Esto sucede porque cuando usamos import x, se crea un espacio de nombres x para evitar conflictos de nombres. Hay que acceder a cada objeto del módulo como x.<nombre>.

Pero cuando usamos from x import y aceptamos añadir y al espacio de nombres global principal. Así que al usar esto tenemos que asegurarnos de que no tenemos un objeto con el mismo nombre en nuestro programa.

Nunca utilices from x import y si ya existe un objeto llamado y

Por ejemplo, en el módulo os hay un método open. Pero incluso tenemos una función incorporada llamada open. Por lo tanto, aquí debemos evitar usar from os import open.

Incluso podemos usar la from x import *, esto importaría todos los métodos, clases de ese módulo al espacio de nombres global del programa. Esta es una mala práctica de programación. Por favor, evítala.

En general, debería evitar from x import y simplemente por los problemas que puede causar en programas a gran escala. Por ejemplo, nunca se sabe si un compañero programador podría querer hacer una nueva función que resulta ser el nombre de una de las funciones existentes. Tampoco sabes si Python cambiará la biblioteca de la que estás importando funciones. Mientras que estos problemas no existirán tan a menudo para los proyectos en solitario, como se ha dicho antes, es una mala práctica de programación y debería evitarse.

Traducido del artículo Python Import Statements Explained