Python Language Definire una funzione con un numero arbitrario di argomenti


Esempio

Numero arbitrario di argomenti posizionali:

La definizione di una funzione in grado di prendere un numero arbitrario di argomenti può essere effettuata con il prefisso di uno degli argomenti con un *

def func(*args):
    # args will be a tuple containing all values that are passed in
    for i in args:
        print(i)

func(1, 2, 3)  # Calling it with 3 arguments
# Out: 1
#      2
#      3

list_of_arg_values = [1, 2, 3]
func(*list_of_arg_values)  # Calling it with list of values, * expands the list
# Out: 1
#      2
#      3 

func()  # Calling it without arguments
# No Output 

Non è possibile fornire un valore predefinito per args , ad esempio func(*args=[1, 2, 3]) genererà un errore di sintassi (non verrà nemmeno compilato).

Non è possibile fornire questi per nome quando si chiama la funzione, ad esempio func(*args=[1, 2, 3]) genererà un TypeError .

Ma se hai già i tuoi argomenti in un array (o qualsiasi altro Iterable ), puoi invocare la tua funzione in questo modo: func(*my_stuff) .

Questi argomenti ( *args ) sono accessibili dall'indice, ad esempio args[0] restituirà il primo argomento

Numero arbitrario di argomenti di parole chiave

Puoi prendere un numero arbitrario di argomenti con un nome definendo un argomento nella definizione con due * di fronte ad esso:

def func(**kwargs):
    # kwargs will be a dictionary containing the names as keys and the values as values
    for name, value in kwargs.items():
        print(name, value)

func(value1=1, value2=2, value3=3)   # Calling it with 3 arguments
# Out: value1 1
#      value2 2
#      value3 3

func()                               # Calling it without arguments
# No Out put

my_dict = {'foo': 1, 'bar': 2}
func(**my_dict)                      # Calling it with a dictionary
# Out: foo 1
#      bar 2

Non è possibile fornire questi senza nomi, ad esempio func(1, 2, 3) genererà un TypeError .

kwargs è un semplice dizionario Python nativo. Ad esempio, args['value1'] fornirà il valore per argomento value1 . Assicurati di controllare in anticipo che c'è un tale argomento o che verrà sollevato un KeyError .

avvertimento

È possibile combinarli con altri argomenti opzionali e obbligatori ma l'ordine all'interno della definizione è importante.

Gli argomenti posizionale / parola chiave vengono prima. (Argomenti richiesti).
Poi vengono gli argomenti arbitrari *arg . (Opzionale).
Quindi gli argomenti con parole chiave vengono dopo. (Necessario).
Infine viene la parola chiave arbitraria **kwargs . (Opzionale).

#       |-positional-|-optional-|---keyword-only--|-optional-|
def func(arg1, arg2=10 , *args, kwarg1, kwarg2=2, **kwargs):
     pass
  • deve essere fornito arg1 , altrimenti viene sollevato un TypeError . Può essere dato come argomento posizionale ( func(10) ) o parola chiave ( func(arg1=10) ).
  • kwarg1 deve essere fornito, ma può essere fornito solo come argomento-chiave: func(kwarg1=10) .
  • arg2 e kwarg2 sono opzionali. Se il valore deve essere modificato, si applicano le stesse regole di arg1 (posizionale o parola chiave) e kwarg1 (solo parola chiave).
  • *args acquisisce parametri posizionali aggiuntivi. Ma nota, che arg1 e arg2 devono essere forniti come argomenti posizionali per passare argomenti a *args : func(1, 1, 1, 1) .
  • **kwargs tutti i parametri aggiuntivi delle parole chiave. In questo caso qualsiasi parametro che non sia arg1 , arg2 , kwarg1 o kwarg2 . Ad esempio: func(kwarg3=10) .
  • In Python 3, puoi usare * da solo per indicare che tutti gli argomenti successivi devono essere specificati come parole chiave. Ad esempio la funzione math.isclose in Python 3.5 e successive viene definita usando def math.isclose (a, b, *, rel_tol=1e-09, abs_tol=0.0) , il che significa che i primi due argomenti possono essere forniti in modo posizionale ma facoltativo il terzo e il quarto parametro possono essere forniti solo come argomenti di parole chiave.

Python 2.x non supporta i parametri solo per le parole chiave. Questo comportamento può essere emulato con kwargs :

def func(arg1, arg2=10, **kwargs):
    try:
        kwarg1 = kwargs.pop("kwarg1")
    except KeyError:
        raise TypeError("missing required keyword-only argument: 'kwarg1'")

    kwarg2 = kwargs.pop("kwarg2", 2)
    # function body ...

Nota sulla denominazione

La convenzione di denominazione opzionali argomenti posizionali args e opzionali argomenti chiave kwargs è solo una convenzione è possibile utilizzare qualsiasi nome che ti piace, ma è utile per seguire la convenzione in modo che gli altri sanno cosa si sta facendo, o anche te più tardi quindi per favore fate.

Nota sull'unicità

Qualsiasi funzione può essere definita con none o un *args e nessuno o uno **kwargs ma non con più di uno di ciascuno. Anche *args deve essere l'ultimo argomento posizionale e **kwargs deve essere l'ultimo parametro. Il tentativo di utilizzare più di uno dei due genererà un'eccezione di Errore di sintassi.

Nota sulle funzioni di annidamento con argomenti opzionali

È possibile annidare tali funzioni e la consueta convenzione è rimuovere gli elementi che il codice ha già gestito, ma se si stanno passando i parametri è necessario passare arg facoltativi di posizione con un prefisso * e arg parole facoltative con un prefisso ** , altrimenti gli argomenti vengono passati come elenco o tupla e kwargs come un singolo dizionario. per esempio:

def fn(**kwargs):
    print(kwargs)
    f1(**kwargs)

def f1(**kwargs):
    print(len(kwargs))

fn(a=1, b=2)
# Out:
# {'a': 1, 'b': 2}
# 2