Ricerca…


Osservazioni

Ci sono alcune cose da notare:

  1. I nomi args e kwargs sono usati per convenzione, non fanno parte delle specifiche del linguaggio. Quindi, questi sono equivalenti:

     def func(*args, **kwargs):
         print(args)
         print(kwargs)
    

     def func(*a, **b):
         print(a)
         print(b)
    
  2. Potresti non avere più di un args o più di un parametro kwargs (tuttavia non sono necessari)

     def func(*args1, *args2):
     #   File "<stdin>", line 1
     #     def test(*args1, *args2):
     #                      ^
     # SyntaxError: invalid syntax
    

     def test(**kwargs1, **kwargs2):
     #   File "<stdin>", line 1
     #     def test(**kwargs1, **kwargs2):
     #                       ^
     # SyntaxError: invalid syntax
    
  3. Se qualche argomento posizionale segue *args , sono argomenti solo per parole chiave che possono essere passati solo per nome. Una singola stella può essere usata al posto di *args per forzare i valori come argomenti della parola chiave senza fornire una lista di parametri variadici. Gli elenchi di parametri solo per parole chiave sono disponibili solo in Python 3.

     def func(a, b, *args, x, y):
         print(a, b, args, x, y)
    
     func(1, 2, 3, 4, x=5, y=6)
     #>>> 1, 2, (3, 4), 5, 6
    

     def func(a, b, *, x, y):
         print(a, b, x, y)
    
     func(1, 2, x=5, y=6)
     #>>> 1, 2, 5, 6
    
  4. **kwargs deve arrivare per ultimo nell'elenco dei parametri.

     def test(**kwargs, *args):
     #   File "<stdin>", line 1
     #     def test(**kwargs, *args):
     #                      ^
     # SyntaxError: invalid syntax
    

Usare * args durante la scrittura di funzioni

Puoi usare la stella * quando scrivi una funzione per raccogliere tutti gli argomenti posizionali (cioè senza nome) in una tupla:

def print_args(farg, *args):
   print("formal arg: %s" % farg)
   for arg in args:
       print("another positional arg: %s" % arg)

Metodo di chiamata:

print_args(1, "two", 3)

In questa chiamata, farg verrà assegnato come sempre, e gli altri due verranno inseriti nella tupla degli args, nell'ordine in cui sono stati ricevuti.

Usare ** kwargs durante la scrittura di funzioni

È possibile definire una funzione che accetta un numero arbitrario di argomenti di parole chiave (denominati) utilizzando la doppia stella ** prima del nome di un parametro:

def print_kwargs(**kwargs):
    print(kwargs)

Quando chiama il metodo, Python costruirà un dizionario di tutti gli argomenti delle parole chiave e lo renderà disponibile nel corpo della funzione:

print_kwargs(a="two", b=3)
# prints: "{a: "two", b=3}"

Si noti che il parametro ** kwargs nella definizione della funzione deve sempre essere l'ultimo parametro e corrisponderà solo agli argomenti passati dopo quelli precedenti.

def example(a, **kw):
    print kw

example(a=2, b=3, c=4) # => {'b': 3, 'c': 4}

All'interno del corpo della funzione, kwargs viene manipolato allo stesso modo di un dizionario; per poter accedere ai singoli elementi in kwargs fai semplicemente scorrere come faresti con un normale dizionario:

def print_kwargs(**kwargs):
    for key in kwargs:
        print("key = {0}, value = {1}".format(key, kwargs[key])) 

Ora, chiamando print_kwargs(a="two", b=1) mostra il seguente output:

print_kwargs(a = "two", b = 1)
key = a, value = "two"
key = b, value = 1

Usare * args quando si chiamano le funzioni

Un caso di uso comune per *args in una definizione di funzione è delegare l'elaborazione a una funzione di tipo wrapper o ereditata. Un tipico esempio potrebbe essere nel metodo __init__ una classe

class A(object):
    def __init__(self, b, c):
        self.y = b
        self.z = c

class B(A):
    def __init__(self, a, *args, **kwargs):
        super(B, self).__init__(*args, **kwargs)
        self.x = a

Qui, il a parametro viene elaborato dalla classe figlio dopo tutti gli altri argomenti (posizionali e parole chiave) sono passati su - ed elaborati dal - la classe di base.

Per esempio:

b = B(1, 2, 3)
b.x  # 1
b.y  # 2
b.z  # 3

Quello che succede qui è la funzione di classe B __init__ vede gli argomenti 1, 2, 3 . Sa che ha bisogno di prendere un argomento posizionale ( a ), quindi afferra il primo argomento passato in ( 1 ), quindi nell'ambito della funzione a == 1 .

Successivamente, vede che è necessario prendere un numero arbitrario di argomenti posizionali ( *args ) in modo che tenga il resto degli argomenti posizionali passati in ( 1, 2 ) e li inserisca in *args . Ora (nell'ambito della funzione) args == [2, 3] .

Quindi, chiama la funzione __init__ classe A con *args . Python vede * di fronte a arg e "decomprime" la lista in argomenti. In questo esempio, quando la classe B 's __init__ funzione chiama classe A ' s __init__ funzione, ma passa gli argomenti 2, 3 (cioè A(2, 3) ).

Infine, imposta la propria proprietà x sul primo argomento posizionale a , che equivale a 1 .

Usare ** kwargs quando si chiamano le funzioni

È possibile utilizzare un dizionario per assegnare valori ai parametri della funzione; utilizzando i parametri nome come chiavi nel dizionario e il valore di questi argomenti associati a ogni chiave:

def test_func(arg1, arg2, arg3): # Usual function with three arguments
   print("arg1: %s" % arg1)
   print("arg2: %s" % arg2)
   print("arg3: %s" % arg3)

# Note that dictionaries are unordered, so we can switch arg2 and arg3. Only the names matter.
kwargs = {"arg3": 3, "arg2": "two"}

# Bind the first argument (ie. arg1) to 1, and use the kwargs dictionary to bind the others
test_var_args_call(1, **kwargs) 

Usare * args quando si chiamano le funzioni

L'effetto dell'utilizzo dell'operatore * su un argomento quando si chiama una funzione è quello di decomprimere l'elenco o un argomento di tupla

def print_args(arg1, arg2):
    print(str(arg1) + str(arg2))

a = [1,2]
b = tuple([3,4])

print_args(*a)
# 12
print_args(*b)
# 34

Si noti che la lunghezza dell'argomento speciale deve essere uguale al numero degli argomenti della funzione.

Un idioma python comune è quello di utilizzare l'operatore di disimballaggio * con la funzione zip per invertire i suoi effetti:

a = [1,3,5,7,9]
b = [2,4,6,8,10]

zipped = zip(a,b)
# [(1,2), (3,4), (5,6), (7,8), (9,10)]

zip(*zipped)
# (1,3,5,7,9), (2,4,6,8,10)

Argomenti richiesti solo per parola chiave e parola chiave

Python 3 consente di definire argomenti di funzione che possono essere assegnati solo da parole chiave, anche senza valori predefiniti. Questo viene fatto usando la stella * per consumare ulteriori parametri posizionali senza impostare i parametri della parola chiave. Tutti gli argomenti dopo * sono argomenti con parole chiave (cioè non posizionali). Si noti che se agli argomenti con parole chiave non viene assegnato un valore predefinito, sono comunque necessari quando si chiama la funzione.

def print_args(arg1, *args, keyword_required, keyword_only=True):
    print("first positional arg: {}".format(arg1))
    for arg in args:
        print("another positional arg: {}".format(arg))
    print("keyword_required value: {}".format(keyword_required))
    print("keyword_only value: {}".format(keyword_only))
    
print(1, 2, 3, 4) # TypeError: print_args() missing 1 required keyword-only argument: 'keyword_required'
print(1, 2, 3, keyword_required=4) 
# first positional arg: 1
# another positional arg: 2
# another positional arg: 3
# keyword_required value: 4
# keyword_only value: True

Popolazione dei valori di kwarg con un dizionario

def foobar(foo=None, bar=None):
    return "{}{}".format(foo, bar)

values = {"foo": "foo", "bar": "bar"}

foobar(**values) # "foobar"

** kwargs e valori predefiniti

Per utilizzare i valori predefiniti con ** kwargs

def fun(**kwargs):
    print kwargs.get('value', 0)

fun()
# print 0
fun(value=1)
# print 1


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow