Los **kwarg
Parte de la sección Object Oriented Programming del Journey de Python de Coddy — lección 43 de 64.
**kwargs es la abreviatura de "keyword arguments" (argumentos de palabra clave). Permite que una función acepte cualquier número de argumentos con nombre (como pares key=value) sin tener que definirlos todos de antemano.
Cómo funciona:
*args→ recolecta argumentos posicionales adicionales en una tupla**kwargs→ recolecta argumentos de palabras clave adicionales en un diccionario
Ejemplo sencillo
Empecemos con el ejemplo más sencillo posible:
def greet(**kwargs):
print(kwargs)
greet(name="Alice", age=25, country="Australia")Salida:
{'name': 'Alice', 'age': 25, 'country': 'Australia'}Como puedes ver, **kwargs recopila automáticamente todos los argumentos de palabra clave en un diccionario.
Uso del diccionario
Dado que kwargs ya es un diccionario, puedes recorrerlo directamente:
def print_info(**kwargs):
print("Information received:")
for key, value in kwargs.items():
print(f"{key}: {value}")
print_info(name="Bob", age=30, job="Teacher")Salida:
Information received:
name: Bob
age: 30
job: TeacherMezclando parámetros regulares con **kwargs
Puedes combinar parámetros regulares con **kwargs:
def create_profile(name, **details):
print(f"Creating profile for: {name}")
print("Additional details:")
for key, value in details.items():
print(f" {key}: {value}")
create_profile("Sarah", age=28, city="London", hobby="Reading")Salida:
Creating profile for: Sarah
Additional details:
age: 28
city: London
hobby: Reading**kwargs** vacíos
Si no se pasan argumentos de palabra clave, kwargs será un diccionario vacío:
def show_data(**kwargs):
if kwargs:
print("Data:", kwargs)
else:
print("No data provided")
show_data() # Sin argumentos
show_data(item="apple") # Con argumentosSalida:
No data provided
Data: {'item': 'apple'}Ejemplo del mundo real: Clase con **kwargs
Aquí tienes cómo podrías usar **kwargs en una clase:
class Person:
def __init__(self, name, **kwargs):
self.name = name
self.details = kwargs
def show_info(self):
print(f"Name: {self.name}")
for key, value in self.details.items():
print(f"{key}: {value}")
person = Person("Alice", age=25, city="New York", job="Engineer")
person.show_info()Resultado:
Name: Alice
age: 25
city: New York
job: EngineerDesempaquetado de diccionarios
También puedes desempaquetar diccionarios al llamar a funciones:
def display_settings(**kwargs):
for setting, value in kwargs.items():
print(f"{setting} = {value}")
settings = {"debug": True, "verbose": False, "timeout": 30}
display_settings(**settings) # Desempaqueta el diccionarioSalida:
debug = True
verbose = False
timeout = 30Puntos clave:
**kwargsrecopila argumentos de palabras clave en un diccionario; no se necesita conversión, ya es uno- El nombre
kwargses convencional: podrías usar cualquier nombre después de** - Úsalo cuando quieras firmas de función flexibles
- Ideal para manejar parámetros opcionales o ajustes de configuración
Desafío
FácilEn este desafío, implementarás un sistema de creación de personas con una cobertura de pruebas exhaustiva.
Necesitas editar solo el archivo person_creator.py, siguiendo los comentarios TODO que guían tu implementación. El archivo contiene una estructura de clase para crear y gestionar objetos de persona con varias propiedades.
Hoja de referencia
El parámetro **kwargs permite que un método acepte cualquier número de argumentos de palabra clave, recogiéndolos en un diccionario:
class Person:
def __init__(self, name, **kwargs):
self.name = name
self.details = kwargs
def show_info(self):
print(f"Name: {self.name}")
for key, value in self.details.items():
print(f"{key}: {value}")
person = Person("Alice", age=25, city="New York", job="Engineer")Combine parámetros regulares, *args y **kwargs:
class Logger:
def log(self, level, *messages, **options):
timestamp = options.get('timestamp', False)
color = options.get('color', 'default')
if timestamp:
print("[2024-01-01 12:00:00]", end=" ")
print(f"[{level}]", end=" ")
for message in messages:
print(message, end=" ")
logger = Logger()
logger.log("INFO", "User", "logged", "in", timestamp=True, color="green")Desempaquete diccionarios al llamar a métodos usando **:
settings = {"debug": True, "verbose": False, "log_level": "INFO"}
config = Config(**settings) # Unpacks the dictionaryAcceda a los valores de **kwargs utilizando métodos de diccionario:
def get_setting(self, key, default=None):
return self.settings.get(key, default)
# Iterate through all kwargs
for key, value in self.settings.items():
print(f"{key} = {value}")Pruébalo tú mismo
from person_creator import create_person
# Manejador de casos de prueba exhaustivo
test_case = input()
if test_case == "basic_test":
create_person(name="John", age=25, occupation="Engineer")
# Salida:
# Person created with properties:
# name: John
# age: 25
# occupation: Engineer
elif test_case == "empty_test":
create_person()
# Salida:
# Person created with properties:
# (no additional output since there are no properties)
elif test_case == "many_properties":
create_person(name="Alice", age=30, occupation="Doctor", city="New York",
country="USA", hobby="Reading", email="alice@example.com")
# Salida:
# Person created with properties:
# name: Alice
# age: 30
# occupation: Doctor
# city: New York
# country: USA
# hobby: Reading
# email: alice@example.com
elif test_case == "special_characters":
create_person(name="Bob", email="bob@example.com", phone="123-456-7890")
# Salida:
# Person created with properties:
# name: Bob
# email: bob@example.com
# phone: 123-456-7890
elif test_case == "numeric_keys":
create_person(name="Charlie", age=35, height=175, weight=70)
# Salida:
# Person created with properties:
# name: Charlie
# age: 35
# height: 175
# weight: 70
elif test_case == "boolean_values":
create_person(name="David", is_student=True, is_employed=False)
# Salida:
# Person created with properties:
# name: David
# is_student: True
# is_employed: False
elif test_case == "nested_structures":
create_person(name="Eve", hobbies=["Reading", "Swimming", "Coding"],
address={"city": "Boston", "state": "MA", "zip": "02108"})
# Salida:
# Person created with properties:
# name: Eve
# hobbies: ['Reading', 'Swimming', 'Coding']
# address: {'city': 'Boston', 'state': 'MA', 'zip': '02108'}
elif test_case == "unicode_characters":
create_person(name="José", city="São Paulo", country="Brasil")
# Salida:
# Person created with properties:
# name: José
# city: São Paulo
# country: Brasil
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Object Oriented Programming
1Fundamentos de la POO
Archivos externosIntroducción a la POOClases vs ObjetosEl parámetro selfMétodosAtributosMétodo constructor (__init__)Resumen - Calculadora simple4Herencia
Herencia básicaLa función super()Sobrescritura de métodosHerencia múltipleOrden de resolución de métodosResumen - Jerarquía de empleados7Métodos especiales
Introducción a los métodos mágicosSobrecarga de operadoresMétodos mágicos de contenedoresRepaso - Lista personalizada10Patrones de diseño Parte 1
Introducción a los patrones de diseñoPatrón SingletonPatrón FactoryPatrón ObserverPatrón Strategy2Decoradores
Introducción a los decoradoresDecorador propertyDecorador de métodos estáticosDecorador de métodos de clase5Polimorfismo
Sobreescritura de métodos revisitadaDuck TypingClases y métodos abstractosDiseño de interfacesResumen - Calculadora de figuras8Conceptos avanzados de POO
Composición vs. HerenciaMixinsMétodos estáticos y de claseDecoradores de claseGestores de contexto11Patrones de diseño, parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón Composite3Propiedades de clase
Variables de instancia vs de claseDecoradores de propiedadesAtributos privadosResumen - Gestor de cuentas bancarias