Lecciones del módulo (2/4)
Parámetros por defecto y keyword
Los parámetros de las funciones pueden tener valores por defecto: si el llamador no los pasa, se usan los valores por defecto. También puedes llamar a una función pasando parámetros por nombre (keyword arguments).
Parámetros por defecto
def saluta(nome, saluto="Ciao"):
return f"{saluto}, {nome}!"
saluta("Ada") # 'Ciao, Ada!'
saluta("Ada", "Hello") # 'Hello, Ada!'Los parámetros con valores por defecto deben ir después de los que no los tienen:
def f(a, b=1): # OK
def f(a=1, b): # SyntaxErrorArgumentos de palabras clave
Puedes pasar argumentos por nombre, en cualquier orden, lo que hace que la llamada sea más legible:
def crea_utente(nome, eta, attivo=True):
return {"nome": nome, "eta": eta, "attivo": attivo}
crea_utente("Ada", 36)
crea_utente(nome="Ada", eta=36, attivo=False)
crea_utente(eta=36, nome="Ada") # any order when all are keywordRegla de oro: en una llamada, los argumentos posicionales van ANTES de los argumentos de palabras clave.
crea_utente("Ada", eta=36) # OK
crea_utente(nome="Ada", 36) # SyntaxError⚠️ La trampa del valor por defecto mutable
NUNCA uses un objeto mutable (lista, diccionario, conjunto) como valor por defecto: el valor por defecto se evalúa UNA VEZ, cuando se define la función, y se comparte entre todas las llamadas.
def aggiungi(elemento, lista=[]): # BUG!
lista.append(elemento)
return lista
aggiungi(1) # [1]
aggiungi(2) # [1, 2] !!! not [2] as you'd expect
aggiungi(3) # [1, 2, 3]El patrón correcto: usa None como centinela y créalo dentro:
def aggiungi(elemento, lista=None):
if lista is None:
lista = []
lista.append(elemento)
return listaEl peligro de los argumentos por defecto mutables
Nunca uses objetos mutables (como listas o diccionarios) como valores predeterminados para los parámetros: por ejemplo def add(x, my_list=[]). El valor predeterminado se evalúa solo una vez cuando se define la función, lo que significa que las llamadas posteriores compartirán exactamente el mismo objeto mutable. La mejor práctica es usar None:
def add(x, my_list=None):
if my_list is None:
my_list = []
my_list.append(x)
return my_listPruébalo tú
Define `power(base, exponent=2)` que devuelva base ** exponent. Calcula `square = power(5)` y `cube = power(5, exponent=3)`. Evalúa `(square, cube)`.
Mostrar pista
return base ** exponent
Solución disponible después de 3 intentos
Ejercicio de repaso
Define `create_record(name, values=None)` que, cuando values sea None, use una lista vacía nueva. Añade 1 a values y devuelve el diccionario del registro {'name': name, 'values': values}. Llámalo dos veces sin pasar values y asigna a `a` y `b`. Evalúa `(a['values'], b['values'])`.
Mostrar pista
Usa None como el valor por defecto y crea la lista dentro de la función.
Solución disponible después de 3 intentos
Desafío adicional
Define una función `greet(name, message="Hello")` que devuelva la cadena formateada `"{message}, {name}!"`. Prueba la función llamando a `greet("Bob")` como última expresión.
Mostrar pista
Usa un parámetro por defecto message="Hello" y una f-string para el saludo devuelto.
Solución disponible después de 3 intentos