2.15. Argumentos

Una función puede llamarse de varias maneras, y sus parámetros pueden declararse de varias formas. Las combinaciones parecen intimidantes al principio; tres o cuatro patrones cubren casi todo en la práctica.

2.15.1. Argumentos posicionales y por palabra clave

La llamada más simple pasa los argumentos por posición: el primer valor va al primer parámetro, el segundo al segundo, y así sucesivamente:

def rect(x, y, w, h):
    return (x, y, w, h)

rect(10, 20, 100, 50)

La misma llamada puede pasar los argumentos por palabra clave, nombrando explícitamente cada parámetro:

rect(x=10, y=20, w=100, h=50)

Los argumentos por palabra clave son independientes del orden y hacen que las llamadas se autodocumenten, a costa de escribir más. Los argumentos posicionales y por palabra clave pueden mezclarse en una sola llamada, pero todos los posicionales deben aparecer antes de cualquier palabra clave:

rect(10, 20, w=100, h=50)         # OK
rect(x=10, 20, 100, 50)           # SyntaxError

2.15.2. Valores por defecto

Un parámetro puede declarar un valor por defecto que se usa cuando quien llama no proporciona uno:

def greet(name, greeting="hello"):
    print(greeting, name)

greet("Alice")                    # hello Alice
greet("Alice", "hi")              # hi Alice
greet("Alice", greeting="hey")    # hey Alice

Los parámetros con valores por defecto deben ir después de los parámetros sin valores por defecto en la línea def.

Advertencia

Los valores por defecto se evalúan una sola vez, cuando se ejecuta el def, no en cada llamada. Usar un valor por defecto mutable ([], {}) hace que el mismo objeto se comparta entre todas las llamadas que toman el valor por defecto. Usa None como centinela en su lugar:

def append_to(item, target=None):
    if target is None:
        target = []
    target.append(item)
    return target

2.15.3. Longitud variable: *args y **kwargs

Un parámetro precedido por * recopila cualquier argumento posicional sobrante en una tuple. Un parámetro precedido por ** recopila cualquier argumento por palabra clave sobrante en un dict. Los nombres convencionales son args y kwargs, pero funciona cualquier identificador:

def report(label, *values, **options):
    print(label, values, options)

report("temps", 21, 22, 23, unit="C", precision=1)

Salida:

temps (21, 22, 23) {'unit': 'C', 'precision': 1}

Una función rara vez necesita ambos. El uso más común es reenviar argumentos desde un envoltorio a una llamada interna:

def log_and_call(func, *args, **kwargs):
    print("calling", func.__name__)
    return func(*args, **kwargs)

La sintaxis reflejada en el sitio de la llamada desempaqueta un iterable en argumentos posicionales (*) o un dict en argumentos por palabra clave (**):

point = (10, 20, 100, 50)
rect(*point)                      # same as rect(10, 20, 100, 50)

kwargs = {"x": 10, "y": 20, "w": 100, "h": 50}
rect(**kwargs)                    # same as rect(x=10, y=20, ...)

2.15.4. Parámetros solo por palabra clave

Un * por sí solo en la lista de parámetros (no adjunto a un nombre) marca todos los parámetros que le siguen como solo por palabra clave: quien llama debe usar el nombre:

def crop(buffer, *, x, y, w, h):
    ...

crop(buffer, x=0, y=0, w=100, h=100)   # OK
crop(buffer, 0, 0, 100, 100)           # TypeError

Usa esto para banderas booleanas y otros argumentos donde un valor pelado en el sitio de la llamada no se explicaría por sí mismo.