¿Qué son los argumentos por defecto en Python? ¡Explicación completa desde lo básico hasta precauciones y usos!

目次

1. ¿Qué son los argumentos predeterminados en Python? [Explicación amable para principiantes]

Al usar funciones en Python, puede ser tedioso pasar valores a todos los argumentos en algunos casos. En tales situaciones, los argumentos predeterminados resultan útiles. Al configurar argumentos predeterminados, se pueden omitir los argumentos al llamar a la función, lo que permite escribir código más conciso y flexible. Aquí explicamos el concepto básico de los argumentos predeterminados y su uso.

1.1 ¿Qué son los argumentos predeterminados?

En las funciones de Python, es posible establecer valores predeterminados (valores iniciales) para los argumentos. A esto se le llama «argumentos predeterminados». Al definir una función con argumentos predeterminados, se pueden omitir argumentos específicos al llamarla, y en ese caso, se aplica automáticamente el valor predeterminado especificado.

Sintaxis básica de los argumentos predeterminados

def nombre_función(nombre_arg=valor_predeterminado):
    procesamiento

Al usar esta sintaxis, se pueden omitir los argumentos de la función, mejorando la legibilidad y flexibilidad del código.

1.2 Uso básico de los argumentos predeterminados

Veamos un ejemplo de código real para entender el uso de los argumentos predeterminados en Python.

Ejemplo básico

def greet(name="Invitado"):
    print(f"¡Hola, {name}!")

greet()  # Salida: ¡Hola, Invitado!
greet("Satō")  # Salida: ¡Hola, Satō!

En la función anteriorgreet(), se ha establecido el valor predeterminado de name como "Invitado". Si se llama a la función sin argumentos, name será "Invitado". Por otro lado, si se especifica un argumento como en greet("Satō"), ese valor tiene prioridad.

Función con múltiples argumentos predeterminados

También es posible establecer múltiples argumentos predeterminados.

def introduce(name="Anónimo", age=20):
    print(f"Soy {name}. Tengo {age} años.")

introduce()  # Salida: Soy Anónimo. Tengo 20 años.
introduce("Tanaka")  # Salida: Soy Tanaka. Tengo 20 años.
introduce("Tanaka", 25)  # Salida: Soy Tanaka. Tengo 25 años.

De esta manera, al establecer valores predeterminados para múltiples argumentos, se puede variar de forma flexible la forma de llamar a la función.

Ventajas de usar argumentos predeterminados

El uso de argumentos predeterminados ofrece las siguientes ventajas.

  • El código se simplifica (es posible omitir argumentos no obligatorios)
  • Se previenen errores (se evitan errores por falta de argumentos)
  • Mejora la versatilidad de la función (al proporcionar valores predeterminados, se permiten diversos usos)

1.3 Escenarios donde se utilizan los argumentos predeterminados

Los argumentos predeterminados son útiles en diversas situaciones. Se usan comúnmente en casos como los siguientes.

1. Configuración de opciones

Al preparar configuraciones opcionales como valores predeterminados dentro de una función, se puede crear fácilmente un mecanismo que los usuarios puedan modificar.

def download_file(url, timeout=10):
    print(f"Se descargará {url} en {timeout} segundos.")

download_file("https://example.com")  # Salida: Se descargará https://example.com en 10 segundos.
download_file("https://example.com", 5)  # Salida: Se descargará https://example.com en 5 segundos.

En este caso, se ha establecido el valor predeterminado de timeout como 10, por lo que si no se especifica al llamar, se aplica 10 segundos.

2. Salida de mensajes de log

Al proporcionar un mensaje de log predeterminado al ejecutar una función, se puede realizar una depuración con alta legibilidad.

def log_message(message, level="INFO"):
    print(f"[{level}] {message}")

log_message("Iniciando el procesamiento")  # Salida: [INFO] Iniciando el procesamiento
log_message("Ocurrió un error", "ERROR")  # Salida: [ERROR] Ocurrió un error

En este ejemplo, se ha establecido el valor predeterminado de level como "INFO", por lo que si no se especifica, se registra el log como "INFO".

1.4 Resumen

Los argumentos predeterminados de Python son una función conveniente para diseñar funciones de manera flexible.

  • Al especificar argumentos predeterminados, se puede llamar a la función omitiendo argumentos
  • Es posible establecer múltiples argumentos predeterminados
  • Simplifica el código y mejora la legibilidad y versatilidad
  • Se puede utilizar en muchos escenarios, como la configuración de opciones o la gestión de logs

En la siguiente sección, explicamos los puntos de atención al usar argumentos predeterminados en Python y los errores comunes!

2. Uso básico de los argumentos predeterminados en Python

En la sección anterior, explicamos el concepto básico de los argumentos predeterminados en Python.
En esta sección, explicaremos en detalle cómo utilizar realmente los argumentos predeterminados, con ejemplos de código específicos.

2.1 Definición de funciones con argumentos predeterminados

Las funciones con argumentos predeterminados se pueden definir de la siguiente manera.

def nombre_función(parámetro1=valor_predeterminado1, parámetro2=valor_predeterminado2, ...):
    procesamiento

Ejemplo concreto

def greet(name="Invitado", message="Hola"):
    print(f"{name}, {message}")

greet()  # Salida: Invitado, Hola
greet("Satō")  # Salida: Satō, Hola
greet("Satō", "¿Cómo está?")  # Salida: Satō, ¿Cómo está?

De esta manera, si se omiten los argumentos, se aplican los valores predeterminados, pero si se especifican, se utilizan esos valores.

2.2 Combinación de argumentos predeterminados y argumentos de palabra clave

Al llamar a la función, al utilizar argumentos de palabra clave (keyword arguments), se puede especificar de manera más flexible.

Ejemplo utilizando argumentos de palabra clave

def introduce(name="Anónimo", age=20, country="Japón"):
    print(f"Soy {name}. Tengo {age} años y soy de {country}.")

introduce()  # Salida: Soy Anónimo. Tengo 20 años y soy de Japón.
introduce(name="Tanaka")  # Salida: Soy Tanaka. Tengo 20 años y soy de Japón.
introduce(age=25, name="Yamamoto")  # Salida: Soy Yamamoto. Tengo 25 años y soy de Japón.
introduce(country="Estados Unidos", age=30)  # Salida: Soy Anónimo. Tengo 30 años y soy de Estados Unidos.

Al usar argumentos de palabra clave, se puede llamar a la función sin preocuparse por el orden de los argumentos, lo que mejora la legibilidad del código.

2.3 Casos de uso de los argumentos predeterminados

Al utilizar argumentos predeterminados, se puede hacer el código más conciso en escenarios específicos.

① Registro de logs

Al establecer un nivel de log predeterminado, se puede realizar una gestión unificada de logs.

def log_message(message, level="INFO"):
    print(f"[{level}] {message}")

log_message("Iniciando la aplicación")  
# Salida: [INFO] Iniciando la aplicación

log_message("Ha ocurrido un error", "ERROR")  
# Salida: [ERROR] Ha ocurrido un error

② Parámetros de solicitudes API

Al llamar a la API, al establecer un valor de tiempo de espera predeterminado, se puede prevenir la ocurrencia de errores.

import requests

def fetch_data(url, timeout=10):
    response = requests.get(url, timeout=timeout)
    return response.json()

# Tiempo de espera predeterminado de 10 segundos
data = fetch_data("https://api.example.com/data")

# Solicitud cambiando el tiempo de espera
data = fetch_data("https://api.example.com/data", timeout=5)

③ Simplificación del procesamiento de cálculos

Al usar argumentos predeterminados, se puede diseñar el procesamiento de cálculos de manera más flexible.

def calculate_price(price, tax_rate=0.10):
    return price * (1 + tax_rate)

print(calculate_price(1000))  # Salida: 1100.0 (tasa impositiva del 10%)
print(calculate_price(1000, 0.08))  # Salida: 1080.0 (tasa impositiva del 8%)

2.4 Resumen

  • Al configurar argumentos predeterminados, mejora la facilidad de uso de la función
  • Al usar argumentos de palabra clave, se puede llamar sin preocuparse por el orden de los argumentos
  • Es posible utilizar en escenarios prácticos como salida de logs, solicitudes API, procesamiento de cálculos, etc.

3. Precauciones al usar argumentos predeterminados [Errores comunes y contramedidas]

Los argumentos predeterminados de Python son una función conveniente, pero un uso incorrecto puede causar errores inesperados.
En esta sección, explicamos los puntos de atención al usar argumentos predeterminados, así como errores comunes y sus contramedidas.

3.1 ¡Presta atención al orden de los argumentos predeterminados!

En Python, los argumentos con valores predeterminados deben colocarse después de los argumentos sin valores predeterminados.
Si se invierte el orden, se produce un SyntaxError (error de sintaxis).

Ejemplo incorrecto (se produce un error)

def func(x=0, y):  # Error: No se puede colocar un argumento no predeterminado después de un argumento predeterminado
    print(x, y)

➡ El argumento predeterminado x=0 está antes que y, por lo que Python reporta un error de sintaxis.

Ejemplo correcto

def func(y, x=0):  # OK
    print(x, y)

Al describir primero el argumento sin predeterminado (y), se evita el error.

3.2 No uses objetos mutables (listas o diccionarios) como valores predeterminados

Si se especifica un objeto mutable (modificable) como una lista o diccionario como argumento predeterminado, se produce un comportamiento no deseado.
Esto se debe a que, en Python, el valor del argumento predeterminado se evalúa solo una vez en el momento de la definición de la función y se reutiliza en cada llamada.

Ejemplo incorrecto (se produce un error)

def add_item(item, item_list=[]):
    item_list.append(item)
    return item_list

print(add_item("apple"))  # Salida: ['apple']
print(add_item("banana"))  # Salida: ['apple', 'banana'] ← ¡Comportamiento inesperado!

La lista configurada como argumento predeterminado item_list=[] se mantiene en cada llamada a la función, por lo que los valores se acumulan.

Ejemplo correcto

def add_item(item, item_list=None):
    if item_list is None:
        item_list = []  # Crear una nueva lista cada vez
    item_list.append(item)
    return item_list

print(add_item("apple"))  # Salida: ['apple']
print(add_item("banana"))  # Salida: ['banana'] ← ¡Comportamiento esperado!

Al configurar None como valor predeterminado y crear una nueva lista dentro de la función, se evita el problema.

3.3 ¡Presta atención al momento de evaluación de los argumentos predeterminados!

En Python, el valor del argumento predeterminado se evalúa en el instante en que se define la función, por lo que configurar valores dependientes del tiempo como predeterminados puede causar comportamientos no deseados.

Ejemplo incorrecto (se produce un error)

import datetime

def log_message(message, timestamp=datetime.datetime.now()):
    print(f"[{timestamp}] {message}")

log_message("Primer registro")  
log_message("Segundo registro")  # ¡Se usa la misma marca de tiempo!

➡ El valor predeterminado de timestamp, datetime.datetime.now(), se evalúa en el momento de la definición de la función y se usa el mismo valor en todas las llamadas.

Ejemplo correcto

import datetime

def log_message(message, timestamp=None):
    if timestamp is None:  # Si es None, obtener la hora actual
        timestamp = datetime.datetime.now()
    print(f"[{timestamp}] {message}")

log_message("Primer registro")  
log_message("Segundo registro")  # Se aplican horas diferentes

Al configurar None como valor predeterminado y ejecutar datetime.datetime.now() dentro de la función, se evita el problema.

3.4 ¡Presta atención a la combinación con argumentos de palabra clave!

En funciones con argumentos predeterminados, es necesario prestar atención a la combinación de argumentos posicionales (positional arguments) y argumentos de palabra clave (keyword arguments).

Ejemplo incorrecto (se produce un error)

def greet(name="Invitado", message="Hola"):
    print(f"{name}, {message}")

greet("Hola", name="Satō")  # TypeError: Duplicación de argumento posicional y de palabra clave

Después de pasar "Hola" como argumento posicional para name, se especificó name="Satō", lo que causa un error.

Ejemplo correcto

greet(name="Satō", message="Hola")  # OK
greet("Satō")  # OK

Al usar adecuadamente argumentos posicionales y de palabra clave, se evita el problema.

3.5 Resumen

  • Los argumentos predeterminados deben describirse después de los argumentos sin predeterminados
  • No uses objetos mutables (modificables) como listas o diccionarios en argumentos predeterminados
  • Presta atención al momento de evaluación de los argumentos predeterminados y evita datos dependientes del tiempo usando None
  • Maneja adecuadamente la combinación de argumentos posicionales y de palabra clave

4. Momento de evaluación de los argumentos predeterminados y su impacto

En Python, el valor del argumento predeterminado se evalúa solo una vez en el momento en que se define la función, y después se reutiliza el mismo objeto cada vez que se llama la función.
Si no se entiende esta característica, pueden ocurrir errores no intencionados.
Aquí, explicamos en detalle el momento de evaluación de los argumentos predeterminados e introducimos el uso correcto con ejemplos de código reales.

4.1 ¿Qué es el momento de evaluación de los argumentos predeterminados?

Normalmente, se tiende a pensar que las variables de Python se configuran con un nuevo valor cada vez que se llama la función, pero el punto principal que difiere es que los argumentos predeterminados se evalúan solo una vez en el momento de la definición de la función.

Ejemplo concreto del momento de evaluación

import datetime

def get_current_time(timestamp=datetime.datetime.now()):
    print(f"Hora actual: {timestamp}")

get_current_time()  # Ejemplo de salida: Hora actual: 2025-03-20 12:00:00
get_current_time()  # Ejemplo de salida: Hora actual: 2025-03-20 12:00:00 (¡la misma hora!)

Se puede ver que, incluso si se llama esta función varias veces, se imprime la misma hora.
La razón es que datetime.datetime.now() se evalúa en el momento en que se define la función y se reutiliza el valor de ese momento cada vez que se llama la función.

4.2 Problemas causados por el momento de evaluación de los argumentos predeterminados

Debido a esta característica, pueden ocurrir errores como los siguientes.

Problema 1: Si se configura un objeto mutable (lista, diccionario, etc.) como argumento predeterminado, los datos se comparten

def append_to_list(value, my_list=[]):
    my_list.append(value)
    return my_list

print(append_to_list(1))  # Salida: [1]
print(append_to_list(2))  # Salida: [1, 2] ← ¡resultado diferente al esperado!
print(append_to_list(3))  # Salida: [1, 2, 3]

En lugar de crearse una nueva lista, se reutiliza la lista de la llamada anterior.

Problema 2: Si se configura un diccionario como argumento predeterminado, ocurre el mismo problema

def add_to_dict(key, value, my_dict={}):
    my_dict[key] = value
    return my_dict

print(add_to_dict("a", 1))  # Salida: {'a': 1}
print(add_to_dict("b", 2))  # Salida: {'a': 1, 'b': 2} ← ¡diferente al esperado!

En lugar de crearse un nuevo diccionario cada vez que se llama la función, se reutiliza el diccionario anterior.

4.3 Cómo evitar errores causados por el momento de evaluación de los argumentos predeterminados

Para evitar este tipo de problemas, especificar None como argumento predeterminado y crear un nuevo objeto dentro de la función es la mejor práctica.

Forma correcta de escribirlo (solución)

def append_to_list(value, my_list=None):
    if my_list is None:
        my_list = []  # Crear una nueva lista cada vez
    my_list.append(value)
    return my_list

print(append_to_list(1))  # Salida: [1]
print(append_to_list(2))  # Salida: [2] ← Funciona correctamente
print(append_to_list(3))  # Salida: [3]

Al usar None, se crea una nueva lista cada vez que se llama la función, lo que evita el error.

4.4 ¿Por qué es lo mejor usar None?

En Python, None es un objeto inmutable (no modificable) y se puede crear un nuevo objeto en cada llamada a la función, por lo que tiene las siguientes ventajas.

  • Evita el problema de compartir argumentos predeterminados
  • Al usar una instrucción if explícita, mejora la legibilidad del código
  • Se puede generar dinámicamente un objeto apropiado dentro de la función

Forma correcta de escribirlo para diccionarios

def add_to_dict(key, value, my_dict=None):
    if my_dict is None:
        my_dict = {}  # Crear un nuevo diccionario
    my_dict[key] = value
    return my_dict

print(add_to_dict("a", 1))  # Salida: {'a': 1}
print(add_to_dict("b", 2))  # Salida: {'b': 2} ← Funciona correctamente

Se crea un nuevo diccionario cada vez que se llama la función, por lo que no ocurre el problema de compartir datos.

4.5 Resumen

  • Los argumentos predeterminados de Python se evalúan solo una vez en el momento de la definición de la función y se reutilizan después
  • Si se especifica un objeto mutable (lista, diccionario, etc.) como argumento predeterminado, los datos se comparten y causan errores
  • Como solución, establecer el valor predeterminado en None y crear un nuevo objeto dentro de la función es la mejor práctica
  • Al aprovechar este conocimiento, se pueden evitar errores inesperados y escribir código más seguro
侍エンジニア塾

5. Uso práctico de los argumentos predeterminados en Python

Hasta ahora, hemos explicado el uso básico de los argumentos predeterminados en Python y los puntos a tener en cuenta.
En esta sección, introduciremos formas de usar argumentos predeterminados útiles en el entorno de desarrollo real.
Al usar argumentos predeterminados de manera adecuada, se puede mejorar la legibilidad y mantenibilidad del código.

5.1 Diseño de funciones utilizando argumentos predeterminados

Los argumentos predeterminados se utilizan para mejorar la conveniencia de las funciones.
Son especialmente útiles en escenarios como los siguientes.

① Funciones con valores de configuración

En funciones con opciones de configuración, el uso de argumentos predeterminados permite un diseño flexible.

def connect_to_database(host="localhost", port=3306, user="root", password=""):
    print(f"Conectando a la base de datos: {host}:{port}, usuario: {user}")

connect_to_database()  
# Salida: Conectando a la base de datos: localhost:3306, usuario: root

connect_to_database(host="db.example.com", user="admin")  
# Salida: Conectando a la base de datos: db.example.com:3306, usuario: admin

Al preparar configuraciones predeterminadas, se puede usar fácilmente en casos estándar.

5.2 Escenarios en los que se deben usar argumentos predeterminados y escenarios a evitar

✅ Escenarios en los que se deben usar argumentos predeterminados

  1. Cuando los argumentos de la función son opcionales
  • Ejemplo: valores de configuración (port=3306, timeout=10)
  1. Cuando se quiere proporcionar valores predeterminados usados frecuentemente
  • Ejemplo: nivel de log (level="INFO")
  1. Cuando se quiere hacer la función concisa y definir el comportamiento estándar
  • Ejemplo: nombre de usuario (name="invitado")

❌ Escenarios en los que se deben evitar los argumentos predeterminados

  1. Cuando el valor predeterminado es un objeto mutable (lista o diccionario, etc.)
  • None Usar para inicializar adecuadamente
  1. Cuando el valor debe ser diferente para cada función
  • Ejemplo: hora actual (timestamp=datetime.datetime.now()) se ajusta el momento de evaluación usando None
  1. Cuando el orden de los argumentos es importante
  • Colocar los valores predeterminados al final

5.3 Resumen

  • Usar argumentos predeterminados adecuadamente mejora la legibilidad y flexibilidad del código
  • Es posible usar en varios escenarios como conexión a base de datos, solicitudes API, logging, entrada de usuario, etc.
  • Cumplir reglas como no usar objetos mutables como argumentos predeterminados, prestar atención al orden de los argumentos, etc.
  • ¡Aprovecha los argumentos predeterminados para diseñar funciones de Python más prácticas!

6. Preguntas frecuentes sobre los argumentos predeterminados en Python (FAQ)

Hemos explicado en detalle los argumentos predeterminados en Python hasta ahora, pero al usarlos en la práctica, a menudo surgen diversas dudas.
En esta sección, hemos resumido las preguntas frecuentes sobre los argumentos predeterminados y sus respuestas.

6.1 Preguntas sobre los conceptos básicos de los argumentos predeterminados

P1. ¿Hay alguna restricción en el orden de los argumentos de una función con argumentos predeterminados?

R: Sí, los argumentos con valores predeterminados deben colocarse siempre después de los argumentos sin valores predeterminados.
Si se invierte el orden, se produce un SyntaxError (error de sintaxis).

Ejemplo incorrecto (error)

def func(x=10, y):  # Error: hay un argumento no predeterminado después de un valor predeterminado
    print(x, y)

Ejemplo correcto

def func(y, x=10):  # OK
    print(x, y)

La regla es describir primero los argumentos sin valores predeterminados.

6.2 Preguntas sobre objetos mutables (listas y diccionarios)

P3. ¿Por qué ocurre un error al establecer una lista o un diccionario como argumento predeterminado?

R: En Python, el valor del argumento predeterminado se evalúa solo una vez en el momento de la definición de la función y se reutiliza después, por lo que si se usa un objeto mutable como una lista o un diccionario como valor predeterminado, los datos se comparten.

Ejemplo donde ocurre un error

def add_item(item, item_list=[]):  # Forma peligrosa
    item_list.append(item)
    return item_list

print(add_item("apple"))  # Salida: ['apple']
print(add_item("banana"))  # Salida: ['apple', 'banana'] ← ¡Comportamiento no deseado!

Forma correcta (usando None)

def add_item(item, item_list=None):
    if item_list is None:
        item_list = []  # Crear una nueva lista
    item_list.append(item)
    return item_list

print(add_item("apple"))  # Salida: ['apple']
print(add_item("banana"))  # Salida: ['banana'] ← ¡Funciona correctamente!

Se puede evitar el problema usando None como valor predeterminado y creando un nuevo objeto dentro de la función.

6.3 Otras preguntas sobre argumentos predeterminados

P5. ¿Cuándo se evalúa el argumento predeterminado?

R: El valor del argumento predeterminado se evalúa solo una vez en el momento en que se «define» la función.
Por lo tanto, es necesario tener precaución si se espera un valor diferente cada vez que se llama a la función.

Ejemplo donde ocurre un problema

import datetime

def log_message(message, timestamp=datetime.datetime.now()):
    print(f"[{timestamp}] {message}")

log_message("Primer registro")  
log_message("Segundo registro")  # ¡Se imprime la misma marca de tiempo!

Forma correcta

def log_message(message, timestamp=None):
    if timestamp is None:
        timestamp = datetime.datetime.now()  # Evaluar en el momento de la llamada
    print(f"[{timestamp}] {message}")

log_message("Primer registro")  
log_message("Segundo registro")  # ¡Se imprimen momentos diferentes!

La forma correcta es usar None como valor predeterminado y obtener el valor en el momento adecuado dentro de la función.

6.4 Resumen

  • Los argumentos predeterminados deben colocarse después de los argumentos sin valores predeterminados
  • Al usar argumentos con palabras clave, se puede llamar a la función sin preocuparse por el orden de los argumentos
  • Usar objetos mutables (listas y diccionarios) como argumentos predeterminados puede causar errores, por lo que lo mejor es usar None
  • Tener precaución con el momento de evaluación de los argumentos predeterminados; para valores como datetime.now(), usar None para una evaluación diferida
  • También es posible pasar funciones como argumentos predeterminados para implementar procesamiento dinámico

7. Resumen y próximos pasos

Hemos explicado en detalle los argumentos predeterminados en Python hasta aquí.
Al usar correctamente los argumentos predeterminados, se mejora la legibilidad y flexibilidad del código, y se puede prevenir la aparición de errores.

Como próximos pasos:

  • Crear funciones que utilicen argumentos predeterminados en la práctica y verificar su comportamiento
  • Practicar la configuración de valores predeterminados usando None
  • Probar diseños que combinen argumentos con palabras clave y argumentos predeterminados

¡Domina los argumentos predeterminados en Python y escribe código más eficiente y sin errores! 🚀