Domanda della ricetta in Python: uso di ** kwds anziché argomento specifico con nome nella ricetta itertools [closed]

1

La definizione della funzione qui sotto proviene dalla pagina delle ricette itertools ( link ).

def random_product(*args, **kwds):
    "Random selection from itertools.product(*args, **kwds)"
    pools = map(tuple, args) * kwds.get('repeat', 1)
    return tuple(random.choice(pool) for pool in pools)

La firma della funzione sembrerebbe più leggibile con l'argomento "ripetizione" specificato esplicitamente, ad es.

def random_product(*args, repeat=1)

Ma immagino ci sia una ragione per cui è scritta usando l'idioma generale. Qualcuno può spiegare?

    
posta Stu 09.12.2014 - 15:30
fonte

1 risposta

4

In Python 2, non puoi mettere un argomento parola chiave dopo *args , questo è un errore di sintassi:

>>> import sys
>>> sys.version_info
sys.version_info(major=2, minor=7, micro=8, releaselevel='final', serial=0)
>>> def random_product(*args, repeat=1):
  File "<stdin>", line 1
    def random_product(*args, repeat=1):
                                   ^
SyntaxError: invalid syntax

Se lo metti prima il catch-all posizionale, cattura il primo argomento posizionale:

>>> def random_product(repeat=1, *args): return repeat, args
... 
>>> random_product('foo', 'bar')
('foo', ('bar',))

In Python 2, quindi, l'unica opzione è catturare gli argomenti delle parole chiave arbitrarie con **kw (dato che cattura solo gli argomenti delle parole chiave effettivi, non gli argomenti posizionali) ed estrae repeat da quello.

Python 3 ha regolato ciò che è supportato; ci sono argomenti di parole chiave specificati dopo che *args catch-all è consentito e sono visti come solo parola chiave:

>>> import sys
>>> sys.version_info
sys.version_info(major=3, minor=4, micro=1, releaselevel='final', serial=0)
>>> def random_product(*args, repeat=1):  return args, repeat
... 
>>> random_product('foo', 'bar')
(('foo', 'bar'), 1)
    
risposta data 09.12.2014 - 15:51
fonte

Leggi altre domande sui tag