Skip to content

Argomenti di lunghezza variabile (*args, **kwargs) in Python

Python

In Python, aggiungendo * e ** (uno o due asterischi) all’inizio dei nomi dei parametri nella definizione della funzione, è possibile specificare un numero arbitrario di argomenti (argomenti a lunghezza variabile) quando si chiama la funzione.

Per convenzione, vengono spesso usati i nomi *args (argomenti) e **kwargs (argomenti di parole chiave), ma finché * e ** sono intestati, non ci sono problemi con altri nomi. Il codice di esempio seguente utilizza i nomi *args e **kwargs.

In questo articolo vengono descritti i seguenti contenuti.

  • *args: riceve più argomenti come una tupla
  • **kwargs: ricevi più argomenti di parole chiave come dizionario

Vedere il seguente articolo per le nozioni di base sulle funzioni in Python.

Se si aggiungono * e ** non quando si quando si definisce una funzione, è possibile decomprimere e passare elenchi e chiama agli argomenti.

*args: riceve più argomenti come una tupla

Se si definisce un parametro precedente da qualsiasi * come *args, la funzione può ricevere un numero di argomenti.

def my_sum(*args):
    return sum(args)

print(my_sum(1, 2, 3, 4))
# 10

print(my_sum(1, 2, 3, 4, 5, 6, 7, 8))
# 36

Nella funzione, più argomenti vengono ricevuti come una tupla. Nell’esempio, una tupla viene passata alla funzione sum() per calcolare la somma.

def my_sum2(*args):
    print('args: ', args)
    print('type: ', type(args))
    print('sum : ', sum(args))

my_sum2(1, 2, 3, 4)
# args:  (1, 2, 3, 4)
# type:  <class 'tuple'>
# sum :  10

Può essere utilizzato con argomenti posizionali.

Il valore specificato dopo (a destra) dell’argomento posizionale viene passato come tupla ad args. Se vengono passati solo posizionali argomenti, args sarà una tupla vuota.

def func_args(arg1, arg2, *args):
    print('arg1: ', arg1)
    print('arg2: ', arg2)
    print('args: ', args)

func_args(0, 1, 2, 3, 4)
# arg1:  0
# arg2:  1
# args:  (2, 3, 4)

func_args(0, 1)
# arg1:  0
# arg2:  1
# args:  ()

È possibile definire prima *args, ma in questo caso i parametri definiti dopo *args devono essere specificati dalla parola chiave format name=value alla chiamata della funzione.

L’ultimo valore non viene passato automaticamente all’argomento posizionale e, se non viene specificato come argomento della parola chiave, viene generato TypeError.

def func_args2(arg1, *args, arg2):
    print('arg1: ', arg1)
    print('arg2: ', arg2)
    print('args: ', args)

# func_args2(0, 1, 2, 3, 4)
# TypeError: func_args2() missing 1 required keyword-only argument: 'arg2'

func_args2(0, 1, 2, 3, arg2=4)
# arg1:  0
# arg2:  4
# args:  (1, 2, 3)

Questa funzione esiste una tecnica per definire un parametro denominato * e utilizzare un parametro successivo come argomento di sole parole chiave.

def func_args_kw_only(arg1, *, arg2):
    print('arg1: ', arg1)
    print('arg2: ', arg2)

# func_args_kw_only(100, 200)
# TypeError: func_args_kw_only() takes 1 positional argument but 2 were given

func_args_kw_only(100, arg2=200)
# arg1:  100
# arg2:  200

**kwargs: ricevi più argomenti di parole chiave come dizionario

Se si definisce un parametro preceduto da ** come **kwargs, la funzione può ricevere un numero di argomenti di parole chiave.

Nella funzione, più argomenti di parole chiave vengono ricevuti come un dizionario la cui chiave è il nome dell’argomento e il cui valore è il suo valore.

def func_kwargs(**kwargs):
    print('kwargs: ', kwargs)
    print('type: ', type(kwargs))

func_kwargs(key1=1, key2=2, key3=3)
# kwargs:  {'key1': 1, 'key2': 2, 'key3': 3}
# type:  <class 'dict'>

Può essere utilizzato anche con argomenti posizionali.

def func_kwargs_positional(arg1, arg2, **kwargs):
    print('arg1: ', arg1)
    print('arg2: ', arg2)
    print('kwargs: ', kwargs)

func_kwargs_positional(0, 1, key1=1)
# arg1:  0
# arg2:  1
# kwargs:  {'key1': 1}

Aggiungendo ** a un oggetto dizionario quando si chiama una funzione, è possibile passare ogni elemento a ciascun argomento.

d = {'key1': 1, 'key2': 2, 'arg1': 100, 'arg2': 200}

func_kwargs_positional(**d)
# arg1:  100
# arg2:  200
# kwargs:  {'key1': 1, 'key2': 2}

Vedere l’articolo seguente per i dettagli sulla decompressione degli argomenti delle funzioni.

Un parametro con ** può essere definito solo all’ultimo dell’elenco dei parametri. Se si definisce un altro parametro dopo il parametro con **, SyntaxError viene sollevato.

# def func_kwargs_error(**kwargs, arg):
#     print(kwargs)

# SyntaxError: invalid syntax