Funciones
A medida que tus programas crecen, escribirás la misma lógica en más de un lugar. Las funciones te permiten escribir la lógica una vez, ponerle un nombre y usarla en todas partes. Arréglala en un solo lugar y cada llamada recibe la corrección automáticamente.
def greet(name):
return f"Hello, {name}!"
print(greet("Sofía")) # "Hello, Sofía!"
print(greet("Mateo")) # "Hello, Mateo!"Escríbela una vez, úsala en todas partes, arréglala en un solo lugar.
Definir una función
La palabra clave def inicia una definición de función, seguida por el nombre, paréntesis, dos puntos y un cuerpo indentado. Una función no hace nada hasta que la llamas. Defínela con def, luego llámala por su nombre con ().
def say_hello():
print("Hello!")
say_hello() # llamar a la funciónParámetros y argumentos
Los parámetros son las entradas que tu función espera. Lístalos dentro de los paréntesis. Cuando llamas a la función, los valores que pasas se asocian a los parámetros en orden.
def greet(name, greeting):
print(f"{greeting}, {name}!")
greet("Sofía", "Hello") # "Hello, Sofía!"
greet("Mateo", "Hi") # "Hi, Mateo!"Parámetros vs argumentos
Parámetro es el nombre en la definición de la función. Argumento es el valor real que pasas cuando llamas a la función. En la práctica, las personas usan estas palabras indistintamente. Solo ten en cuenta la distinción al leer documentación.
Valores por defecto
Puedes darles a los parámetros un valor por defecto. Si quien llama no proporciona ese argumento, se usa el valor por defecto. Los parámetros con valores por defecto deben ir después de los parámetros sin valores por defecto.
def greet(name, greeting="Hello"):
print(f"{greeting}, {name}!")
greet("Sofía") # "Hello, Sofía!"
greet("Sofía", "Hi") # "Hi, Sofía!"Los parámetros con valores por defecto deben ir después de los parámetros sin valores por defecto.
Argumentos con nombre
Al llamar a una función, puedes nombrar los argumentos. Esto hace que las llamadas sean legibles, especialmente para funciones con muchos parámetros, y te permite pasarlos en cualquier orden.
def describe_player(name, score, level):
print(f"{name} | Score: {score} | Level: {level}")
describe_player("Sofía", 87, 5) # posicional
describe_player(name="Sofía", level=5, score=87) # con nombre, cualquier orden
describe_player("Sofía", level=5, score=87) # mezcla: posicional primeroValores de retorno
return envía un valor de vuelta a quien hizo la llamada. Sin return, una función devuelve None. Una vez que return se ejecuta, la función sale inmediatamente. Cualquier código después de él en ese bloque se omite.
def add(a, b):
return a + b
result = add(3, 4) # result = 7
print(result)return también sale de la función inmediatamente. Cualquier código después de él en ese bloque no se ejecuta.
Retornar múltiples valores
Python te permite retornar múltiples valores separándolos con comas. Quien llama los recibe como una tupla y puede desempacarlos en nombres separados en una sola línea.
def min_max(numbers):
return min(numbers), max(numbers)
low, high = min_max([3, 7, 1, 9, 4])
print(low, high) # 1 9La sintaxis low, high = ... es desempaquetado: Python asigna cada valor retornado al nombre correspondiente.
Alcance
Las variables creadas dentro de una función existen solo dentro de esa función. No puedes verlas desde afuera. Las variables definidas fuera de todas las funciones son visibles en todas partes, pero no puedes modificarlas desde dentro de una función sin una declaración explícita.
def calculate():
result = 42 # local a esta función
return result
calculate()
print(result) # NameError, result no existe acá afueracount = 0
def increment():
global count # declara que quieres modificar la global
count += 1
increment()
print(count) # 1Usar global debería ser un último recurso. Hace que el código sea más difícil de razonar. Prefiere pasar valores como entrada y retornarlos como salida.
*args y **kwargs
A veces no sabes cuántos argumentos recibirá una función. *args recolecta cualquier número de argumentos posicionales en una tupla. **kwargs recolecta cualquier número de argumentos con nombre en un diccionario. Los nombres args y kwargs son convenciones; lo importante son los asteriscos.
def total(*args):
return sum(args)
total(1, 2, 3) # 6
total(1, 2, 3, 4, 5) # 15def display(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
display(name="Sofía", score=87, level=5)Puedes mezclarlos con parámetros regulares. Los parámetros regulares van primero:
def describe(title, *tags, **metadata):
print(f"{title} | tags: {tags} | meta: {metadata}")
describe("Python intro", "beginner", "python", author="Sofía", year=2024)Docstrings
Un docstring es una cadena al inicio de una función que describe lo que hace. Los editores y herramientas de Python lo usan para mostrar ayuda cuando pasas el cursor sobre una llamada a función. Usa comillas triples y escribe una línea para funciones simples.
def normalise(value, min_val, max_val):
"""Scale a value to the 0-1 range given the known min and max."""
return (value - min_val) / (max_val - min_val)def build_url(base, version, resource, *, secure=True):
"""
Build an API endpoint URL.
Returns a fully-qualified URL string. If secure is False,
the URL will use http instead of https.
"""
scheme = "https" if secure else "http"
base = base.replace("https://", "").replace("http://", "")
return f"{scheme}://{base}/{version}/{resource}"Escribe un docstring para cualquier función que no sea obviamente autoexplicativa por su nombre y firma.
Anotaciones de tipo
Las anotaciones de tipo te permiten indicar qué tipos espera y retorna una función. Python no las hace cumplir en tiempo de ejecución, pero los editores las usan para detectar errores antes de que ejecutes algo. El -> antes de los dos puntos especifica el tipo de retorno.
def greet(name: str, score: int) -> str:
return f"{name} scored {score}"def log(message: str) -> None:
print(f"[LOG] {message}")def top_scores(scores: list[int], n: int) -> list[int]:
return sorted(scores, reverse=True)[:n]Las anotaciones de tipo son opcionales pero valiosas en cualquier función que se vaya a llamar desde múltiples lugares. Son documentación que las herramientas pueden verificar.
Funciones como valores
Las funciones en Python son valores, igual que las cadenas o los números. Puedes asignarlas a variables y pasarlas a otras funciones. Así es como sorted() acepta una función key=.
def double(x):
return x * 2
def apply(func, value):
return func(value)
apply(double, 5) # 10Pasar funciones como argumentos aparece constantemente con sorted(), map() y filter(). También lo verás en el capítulo Lambda, comprensiones y zip.
En la práctica
Dos funciones que trabajan juntas: letter_grade convierte una nota a una letra, y summarise la llama por cada nota en una lista:
def letter_grade(score: int) -> str:
if score >= 90:
return "A"
elif score >= 80:
return "B"
elif score >= 70:
return "C"
else:
return "F"
def summarise(scores: list[int]) -> None:
total = sum(scores)
avg = total / len(scores)
grades = [letter_grade(s) for s in scores]
print(f"Average: {avg:.1f}")
print(f"Grades: {', '.join(grades)}")
summarise([87, 92, 74, 65, 91])
