Pregunta 1Después de ejecutar este código, ¿cuál es el valor de x?def f(value):
value += 10
x = 5
f(x)
print(x)
Argumentos de función y referencias a objetos — los mutables se modifican dentro de las funciones
Comprende cómo se comportan los argumentos de función en Python según sean mutables o inmutables, y evita las trampas comunes.
Cuando llamas a una función, el comportamiento cambia dependiendo de si el argumento es un tipo mutable (list / dict / set) o un tipo inmutable (int / str / tuple). Este artículo recorre esa diferencia y los patrones básicos para escribir funciones seguras.
Argumentos inmutables — los cambios internos no se filtran fuera
Los enteros, flotantes, cadenas y tuplas son inmutables (no se pueden cambiar en el sitio). Recibe uno como argumento y reescríbelo con += 10 o = otro_valor, y la variable del llamador queda intacta.
Por debajo, += 10 crea un nuevo valor y reasigna solo el nombre del argumento interno — el nombre del llamador sigue apuntando al original.
def try_modify_number(value):
value += 10
print(f"dentro: {value}")
x = 5
try_modify_number(x)
print(f"fuera: {x}")
# dentro: 15
# fuera: 5 <- sigue siendo el original
# Lo mismo pasa con cadenas y tuplas
def try_modify_text(text):
text = text + " world"
print(f"dentro: {text}")
message = "hello"
try_modify_text(message)
print(f"fuera: {message}") # hello
Argumentos mutables — los cambios internos se filtran fuera
Por otro lado, cuando pasas un tipo mutable como list / dict / set y llamas a algo como .append() o .update() para modificar el contenido en el sitio, la variable del llamador ve el mismo cambio.
Eso se debe a que en el momento en que se pasa el argumento, el nombre del llamador y el nombre del argumento interno comparten la misma caja. Es el mismo mecanismo que y = x del artículo anterior sobre mutables vs inmutables — ahora ocurriendo en el límite de la llamada.
def try_modify_list(items):
items.append(100)
print(f"dentro: {items}")
my_list = [1, 2, 3]
try_modify_list(my_list)
print(f"fuera: {my_list}")
# dentro: [1, 2, 3, 100]
# fuera: [1, 2, 3, 100] <- el exterior también cambió
# Lo mismo con dicts
def set_role(user, role):
user["role"] = role
admin = {"name": "Ana"}
set_role(admin, "admin")
print(admin) # {'name': 'Ana', 'role': 'admin'}
Cuando las mutaciones internas se filtran fuera, la causa es difícil de rastrear
cart.append(...) parece perfectamente intencional en su propia línea. Pero como el append dentro de la función también alcanza al my_list exterior, puedes acabar con síntomas del tipo «la lista creció en silencio» que aparecen en algún lugar completamente no relacionado.
Modificar solo dentro de la función — protege los argumentos con .copy()
Cuando quieras dejar los datos del llamador en paz y solo cambiar cosas dentro de la función, basta con poner .copy() al comienzo de la función. Copia la lista, dict o set entrante en una caja separada antes de modificarla, y el llamador no se ve afectado.
Devuelve la versión modificada con return, y el llamador puede tener al mismo tiempo el carrito original y el nuevo carrito. Una vez que este patrón sea memoria muscular, estarás escribiendo funciones seguras y libres de efectos secundarios (sin modificación del llamador).
El flujo completo: ① copia el argumento con .copy() en una caja separada → ② edita la copia → ③ devuelve el resultado. Memoriza estos tres pasos y podrás diseñar de forma segura cualquier función que tome argumentos mutables.
def add_item_safely(cart, item):
items = cart.copy() # copia en una caja separada antes de editar
items.append(item)
return items # devuelve el resultado con return
my_cart = ["leche", "pan"]
new_cart = add_item_safely(my_cart, "huevos")
print(my_cart) # ['leche', 'pan'] <- intacto
print(new_cart) # ['leche', 'pan', 'huevos'] <- una lista separada
Verificación de conocimientos
Responde cada pregunta una a una.
Pregunta 2Después de ejecutar este código, ¿cuál es el valor de my_list?def g(items):
items.append(100)
my_list = [1, 2, 3]
g(my_list)
print(my_list)
Pregunta 3Cuando quieres devolver una nueva lista sin modificar la lista del llamador, ¿qué es lo primero que deberías hacer?