Definir funciones
Crea bloques de código reutilizables con def, parámetros y valores de retorno.
- Definir y llamar funciones con def
- Usar parámetros posicionales, de palabra clave y con valor predeterminado
- Devolver valores desde las funciones
- Escribir docstrings para documentar las funciones
De la fórmula a la máquina nombrada
Las matemáticas aborrecen la repetición. Aprendiste como una regla, una definición, usada mil veces, sobre mil entradas distintas:
El def de Python es el mismo movimiento: ligar un nombre a un cálculo, para que cualquier llamador pueda aplicarlo. La función es una máquina con ranuras de entrada etiquetadas y una puerta de salida:
def add(a, b):
return a + b
result = add(3, 5) # 8El nombre, los paréntesis que sostienen los parámetros , los dos puntos que inician la receta, esa es la definición. La llamada add(3, 5) es aplicar la regla en , , exactamente como aplica una regla en .
Definir y llamar
La primera función que escribes cambia el mundo un saludo a la vez:
def greet(name):
"""Print a greeting for the given name."""
print(f"Hello, {name}!")
greet("Alice") # Hello, Alice!Tres partes merecen nombre. Los parámetros son las variables en la definición, las ranuras de entrada . Los argumentos son los valores concretos aportados en el lugar de la llamada, la entrada . Y la línea entre comillas triples de dentro es el docstring: documentación que vive al lado del código, para que help(greet) pueda responder qué hace la función.
Return: la puerta de salida
print manda texto a la pantalla; return entrega un valor de vuelta al llamador. La distinción es sutil y decisiva:
def add(a, b):
return a + b
result = add(3, 5) # result == 8
printed = print("8") # printed es None — print no devuelve nadaUna función sin return devuelve None en silencio, la máquina no produce salida. Cuando quieras que el resultado aritmético de tu función siga fluyendo hacia delante, recuerda: return, no print.
Parámetros con valor predeterminado
Algunos parámetros tienen un ajuste natural que la mayoría de las llamadas conservará. Dales un valor por defecto, y los llamadores podrán anularlo:
def greet(name, greeting="Hello"):
return f"{greeting}, {name}!"
print(greet("Alice")) # Hello, Alice!
print(greet("Bob", "Hey")) # Hey, Bob!La regla de orden es rígida: los parámetros con valor predeterminado van después de los que no lo tienen. def f(x, y=5) es legal; def f(x=1, y) es un error de sintaxis, porque Python resuelve los argumentos por posición desde la izquierda y un hueco sería ambiguo.
Argumentos de palabra clave
Los argumentos también pueden llegar con nombre, lo que compra claridad cuando el conjunto de parámetros crece:
def create_user(name, age, role="student"):
return {"name": name, "age": age, "role": role}
user = create_user(age=25, name="Alice", role="admin")Los argumentos nombrados pueden ir en cualquier orden, el nombre del parámetro es la etiqueta de cada paquete. Una llamada que nombra sus entradas se lee como una frase, y no como un código por descifrar.
*args y **kwargs
¿Y si el número de entradas no se conoce de antemano? Una suma no sabe cuántos sumandos recibirá. *args recoge cualquier número de argumentos posicionales en una tupla; **kwargs recoge los argumentos nombrados en un dict:
def total(*args):
return sum(args)
print(total(1, 2, 3, 4)) # 10
def print_info(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
print_info(name="Alice", age=25)La estrella es el gesto: * despliega la lista de argumentos en un haz. Es la diferencia entre una suma con firma fija y una suma que acepta para cualquier .
Retorno temprano como guardia
Algún código empieza comprobando el único caso que no debe seguir. Razonamientos de la forma “salvo que sea ” se enuncian como una guardia arriba, retornando de inmediato:
def divide(a, b):
if b == 0:
return None
return a / bUna cláusula de guardia comprime un par if/else en una línea recta: el caso de fallo sale pronto y el camino honesto corre sin anidar.
Un ejemplo resuelto: la máquina f
La cuadrática que abrió la lección se vuelve tres declaraciones return:
def quad(x):
"""Devuelve x² − 5x + 6."""
return x * x - 5 * x + 6
quad(2) # 0
quad(3) # 0
quad(1) # 2La misma regla, tres entradas. La fórmula se vuelve una máquina reutilizable: se define una vez, se aplica mil veces, y el docstring deja escrito qué regla encierra.
Errores comunes
- Argumentos mutables por defecto.
def f(items=[])crea una lista compartida entre todas las llamadas, los elementos se amontonan entre llamadas. UsaNonepor defecto y construye la lista dentro. - Olvidar
return. Una función sin él devuelveNone; pediste un valor y recibiste una sombra. - Demasiados parámetros. Pasados tres o cuatro, las ranuras se vuelven un rompecabezas. Agrupa los argumentos afines en un dict o en un dataclass.
- Llamar a una función definida más abajo. Python ejecuta de arriba a abajo; llamar a
f()antes de que eldef fllegue al intérprete lanza unNameError. Define antes de llamar.
🧩 Desafíos
🧩 Desafío, piensa primero, luego revela
Escribe is_palindrome(text) que devuelva True cuando la cadena se lee igual de delante hacia atrás; ignora el caso de las letras.
💡 Respuesta: def is_palindrome(text): return text.lower() == text.lower()[::-1], pasar a minúsculas vuelve simétrica la comparación, y el rebanado invertido [::-1] es la imagen especular.
🧩 Desafío, piensa primero, luego revela
Escribe fizzbuzz(n) que devuelva una lista de 1 a , reemplazando los múltiplos de 3 por "Fizz", los de 5 por "Buzz" y los de ambos por "FizzBuzz".
💡 Respuesta: Los múltiplos de ambos son múltiplos de $\mathrm{lcm}(3,5) = 15$, así que prueba ese caso primero: ["FizzBuzz" if i % 15 == 0 else "Fizz" if i % 3 == 0 else "Buzz" if i % 5 == 0 else i for i in range(1, n+1)].
🤔 Preguntas socráticas
- ¿Por qué los parámetros con valor predeterminado deben ir detrás de los que no lo tienen? ¿Qué se rompería si la regla fuera la inversa?
- ¿Qué te da
*argsque no te dé un único parámetro lista? ¿Cuándo recurres a uno sobre el otro? - ¿Cómo decide Python qué definición aplica cuando existen a la vez
def f(x)ydef f(x, y=5)?
✅ Comprobación rápida
1. ¿Qué devuelve esto? def f(x, y=3): return x + y; f(5)
2. ¿Cuál es la salida? def f(a, b=[]): b.append(a); return b; print(f(1)); print(f(2))