Funciones en Python
Aprende a definir y llamar funciones en Python, usar parámetros, argumentos predeterminados, *args, **kwargs, valores de retorno, alcance y docstrings.
Una función es un bloque de código reutilizable con nombre que realiza una tarea específica. Las funciones te permiten escribir la lógica una vez y llamarla desde cualquier parte del programa — haciendo el código más corto, más fácil de leer y más sencillo de probar. Este capítulo cubre todo lo que necesitas para trabajar con confianza con funciones de Python: definición, parámetros, valores de retorno, argumentos predeterminados, *args y **kwargs, alcance, docstrings, sugerencias de tipo, recursión y uso de funciones de primera clase.
Definir una función
Usa la palabra clave def, un nombre, paréntesis y dos puntos. El cuerpo va indentado un nivel.
def greet(name):
print("Hello, " + name)La función no se ejecuta hasta que la llamas. En el momento de la definición no ocurre nada, excepto que Python almacena el objeto función con el nombre dado.
Llamar a una función
Pasa los argumentos dentro de los paréntesis, haciendo coincidir los nombres de parámetros de la definición.
Valores de retorno
Una función puede devolver un resultado al llamador con la instrucción return. Sin return, Python devuelve None.
def add(a, b):
return a + b
result = add(3, 5)
print(result) # 8Una vez que return se ejecuta, la función se detiene de inmediato — cualquier código posterior en el mismo cuerpo de la función es inalcanzable.
Devolver múltiples valores
Python permite devolver varios valores como una tupla, que puedes desempaquetar en el lado del llamador.
import math
def circle_stats(radius):
area = math.pi * radius ** 2
circumference = 2 * math.pi * radius
return area, circumference
area, circ = circle_stats(5)
print(round(area, 2)) # 78.54
print(round(circ, 2)) # 31.42Parámetros y argumentos
| Término | Significado |
|---|---|
| Parámetro | Nombre de variable en la definición de la función |
| Argumento | Valor real que se pasa al llamar a la función |
Python admite varias formas de pasar argumentos.
Argumentos posicionales
Los argumentos se asignan a los parámetros en orden.
def describe(name, age):
print(name, "is", age, "years old")
describe("Bob", 25) # Bob is 25 years oldArgumentos de palabra clave
Puedes pasar argumentos por nombre, en cualquier orden.
describe(age=25, name="Bob") # Bob is 25 years oldValores predeterminados de parámetros
Proporciona un valor alternativo que se usa cuando el llamador omite ese argumento.
def greet(name="World"):
print("Hello, " + name)
greet() # Hello, World
greet("Alice") # Hello, AlicePrecaución: nunca uses un objeto mutable (lista, dict) como valor predeterminado — se crea una sola vez en el momento de la definición y se comparte entre todas las llamadas. Usa None como valor predeterminado y crea el objeto dentro del cuerpo en su lugar.
# Correct pattern for a mutable default
def append_item(item, lst=None):
if lst is None:
lst = []
lst.append(item)
return lstArgumentos posicionales arbitrarios (*args)
Prefija un nombre de parámetro con * para recoger cualquier número de argumentos posicionales en una tupla.
def total(*numbers):
return sum(numbers)
print(total(1, 2, 3)) # 6
print(total(10, 20)) # 30Argumentos de palabra clave arbitrarios (**kwargs)
Prefija con ** para recoger cualquier número de argumentos de palabra clave en un diccionario.
def describe_person(**info):
for key, value in info.items():
print(key + ": " + str(value))
describe_person(name="Alice", age=30, city="Paris")
# name: Alice
# age: 30
# city: ParisCombinación de tipos de parámetros
Cuando mezclas tipos de parámetros, el orden debe ser: posicionales, *args, solo por palabra clave, **kwargs.
def log(level, *messages, separator=" | ", **meta):
print(level.upper(), separator.join(messages), meta)
log("info", "started", "ready", separator=" — ", version="1.0")
# INFO started — ready {'version': '1.0'}Alcance de variables
Las reglas de alcance de Python siguen la regla LEGB: Local → Enclosing → Global → Built-in.
Una variable definida dentro de una función es local — no se puede acceder a ella desde fuera.
def my_func():
x = 10 # local to my_func
print(x)
my_func()
# print(x) # NameError: name 'x' is not definedPara leer o modificar una variable global dentro de una función, decláraladeclarala con global.
x = 10
def change_x():
global x
x = 20
change_x()
print(x) # 20Usa global con moderación — las funciones que dependen del estado global son más difíciles de probar y reutilizar. Consulta Variables de Python y Variables globales para ver el alcance con más detalle.
Docstrings
Un docstring es una cadena literal colocada inmediatamente después de la línea def. Documenta qué hace la función, qué acepta y qué devuelve. Python lo almacena en el atributo __doc__ de la función y herramientas como help() lo muestran.
def add(a, b):
"""Return the sum of a and b.
Args:
a: First number.
b: Second number.
Returns:
The sum as a number.
"""
return a + b
print(add.__doc__)
# Return the sum of a and b.
# ...Sugerencias de tipo
Las sugerencias de tipo (PEP 484) te permiten anotar los tipos de parámetros y de retorno. Python no las aplica en tiempo de ejecución, pero editores, linters y mypy las usan para detectar errores con anticipación.
def multiply(a: float, b: float) -> float:
return a * b
print(multiply(3, 4)) # 12
print(multiply(2.5, 2.0)) # 5.0Recursión
Una función puede llamarse a sí misma. Esto se llama recursión y es útil para problemas con una estructura naturalmente recursiva (árboles, factoriales, etc.). Toda función recursiva necesita un caso base que detenga la recursión.
def factorial(n):
if n == 0 or n == 1: # base case
return 1
return n * factorial(n - 1)
print(factorial(5)) # 120
print(factorial(0)) # 1Python limita la profundidad de recursión (por defecto 1000) para evitar desbordamientos de pila. Para recursiones profundas, prefiere un enfoque iterativo o usa sys.setrecursionlimit.
Funciones como objetos de primera clase
En Python, las funciones son objetos. Puedes almacenarlas en variables, pasarlas como argumentos y devolverlas desde otras funciones.
def apply(func, value):
return func(value)
def double(n):
return n * 2
print(apply(double, 7)) # 14Esta es la base de las funciones lambda, las funciones de orden superior y los decoradores.
Funciones integradas vs. funciones definidas por el usuario
Python incluye muchas funciones integradas — print(), len(), range(), sum(), sorted() — que siempre están disponibles sin necesidad de importar. Las funciones definidas por el usuario son las que escribes con def. Ambas siguen una sintaxis de llamada idéntica.
Buenas prácticas
- Nombra las funciones como verbos:
calculate_tax()es más claro quetax(). - Haz una sola cosa: una función que valida, guarda y envía un correo electrónico son en realidad tres funciones esperando nacer.
- Escribe un docstring: incluso una sola frase que describa el propósito tiene valor.
- Evita los efectos secundarios cuando sea posible: las funciones que devuelven valores y no modifican ningún estado global son más fáciles de probar.
- Mantén firmas cortas: más de tres o cuatro parámetros es una señal para agrupar datos relacionados en una clase o dict.
- Usa sugerencias de tipo: sirven como documentación ligera y habilitan el análisis estático.