Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Retorno de Valores (La Entrega)

PRINT: EFÍMERO (la salida se desvanece en pantalla) vs. RETURN: TANGIBLE (el valor regresa al código que llamó)

Fig. 9.5: print es efímero; return es tangible.

La diferencia que más confunde a los principiantes no es la sintaxis ni los tipos de datos. Es esta: El Altavoz (print) vs La Entrega (return). Entenderla cambia cómo diseñas tus funciones.

La Metáfora

  1. print() es el Sistema de Altavoces: El robot anuncia por los altavoces: “¡El resultado es 50!”. Tú (el humano) lo escuchas, pero el siguiente robot en la línea no puede agarrar un sonido. El sonido se desvanece en el aire.

  2. return es la Cinta Transportadora: El robot pone una caja física con el número 50 en la cinta y se la pasa al siguiente proceso. El siguiente robot puede tomar esa caja, abrirla y usar el 50 para hacer otra cosa.

El Error Clásico

def suma_mala(a, b):
    print(a + b)  # ANUNCIA el resultado

def suma_buena(a, b):
    return a + b  # ENTREGA el resultado

# Intento de uso
x = suma_mala(5, 5)   # x está VACÍO (None). El número se perdió en el aire.
y = suma_buena(5, 5)  # y vale 10. Tengo el número en la mano.

total = y + 20  # Funciona (30)
total = x + 20  # FALLA:
# TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'

Ese error de None desconcierta a todo el mundo la primera vez. No es un bug del lenguaje: Python cumplió exactamente lo que le pediste. El problema es que pediste la cosa equivocada.

Nota:

  • ¿Es para que el usuario lo lea? → print
  • ¿Es para que el programa siga calculando? → return

La Cinta Entrega Paquetes Dobles (Retorno de Tuplas)

En el capítulo de tuplas viste un adelanto que prometimos retomar. Este es el momento. Una función puede entregar varios valores de un solo envío: separa con comas en el return (Python arma la tupla) y desempaca al recibir:

def dividir(a: int, b: int) -> tuple[int, int]:
    return a // b, a % b       # la tupla (cociente, resto) viaja por la cinta

cociente, resto = dividir(17, 5)
print(cociente)  # 3
print(resto)     # 2

Sin variables globales, sin trucos: dos resultados, un viaje. Lo usarás cada vez que una operación produzca naturalmente más de un dato (el precio y el descuento aplicado, la caja y su pasillo).

Salidas de Emergencia (return Temprano)

Una función puede tener varios return, y el primero que se ejecuta termina el trabajo ahí mismo. Ya viste este patrón con nombre propio en el Capítulo 7: las cláusulas de guarda.

def buscar_producto(inventario: list, id_producto: str) -> dict | None:
    for producto in inventario:
        if producto["id"] == id_producto:
            return producto   # encontrado: salida inmediata
    return None               # recorrido completo sin éxito

Un detalle de la firma antes de seguir: -> dict | None se lee “devuelve un diccionario o None”. En las pistas de tipo, la barra | significa “o”; no es la unión de conjuntos del Capítulo 5.

Y un secreto que explica muchos None misteriosos: si una función llega al final sin return, Python le agrega un return None invisible. Toda función devuelve algo, aunque tú no lo pidas.