Ricerca…


Incarico distruttivo

Nei compiti, puoi dividere un Iterable in valori usando la sintassi "decompressione":

Distruzione come valori

a, b = (1, 2)
print(a)
# Prints: 1
print(b)
# Prints: 2

Se tenti di decomprimere più della lunghezza del iterabile, riceverai un errore:

a, b, c = [1]
# Raises: ValueError: not enough values to unpack (expected 3, got 1)
Python 3.x 3.0

Distruzione come lista

È possibile decomprimere un elenco di lunghezza sconosciuta utilizzando la seguente sintassi:

head, *tail = [1, 2, 3, 4, 5]

Qui, estraiamo il primo valore come scalare e gli altri valori come un elenco:

print(head)
# Prints: 1
print(tail)
# Prints: [2, 3, 4, 5]

Che è equivalente a:

l = [1, 2, 3, 4, 5]
head = l[0]
tail = l[1:]

Funziona anche con più elementi o elementi alla fine dell'elenco:

a, b, *other, z = [1, 2, 3, 4, 5]
print(a, b, z, other)
# Prints: 1 2 5 [3, 4]

Ignorare i valori nei compiti distruttivi

Se ti interessa solo un determinato valore, puoi usare _ per indicare che non sei interessato. Nota: questo sarà ancora impostato su _ , solo la maggior parte delle persone non lo usa come variabile.

a, _ = [1, 2]
print(a)
# Prints: 1
a, _, c = (1, 2, 3)
print(a)
# Prints: 1
print(c)
# Prints: 3
Python 3.x 3.0

Ignorare le liste in compiti distruttivi

Infine, puoi ignorare molti valori usando la sintassi *_ nell'assegnazione:

a, *_ = [1, 2, 3, 4, 5]
print(a)
# Prints: 1

che non è molto interessante, in quanto è possibile utilizzare l'indicizzazione nell'elenco. Dove è bello mantenere il primo e l'ultimo valore in un compito:

 a, *_, b = [1, 2, 3, 4, 5]
 print(a, b)
 # Prints: 1 5

o estrai più valori contemporaneamente:

 a, _, b, _, c, *_ = [1, 2, 3, 4, 5, 6]
 print(a, b, c)
 # Prints: 1 3 5

Argomenti della funzione di imballaggio

Nelle funzioni, è possibile definire un numero di argomenti obbligatori:

def fun1(arg1, arg2, arg3): 
    return (arg1,arg2,arg3)

che renderà la funzione chiamabile solo quando vengono dati i tre argomenti:

fun1(1, 2, 3)

ed è possibile definire gli argomenti come facoltativi, utilizzando i valori predefiniti:

def fun2(arg1='a', arg2='b', arg3='c'):
    return (arg1,arg2,arg3)

quindi puoi chiamare la funzione in molti modi diversi, come:

fun2(1)              → (1,b,c)
fun2(1, 2)           → (1,2,c)
fun2(arg2=2, arg3=3) → (a,2,3)
...

Ma puoi anche usare la sintassi destructuring per impacchettare gli argomenti, così puoi assegnare variabili usando una list o un dict .

Imballaggio di un elenco di argomenti

Considera di avere una lista di valori

l = [1,2,3]

Puoi chiamare la funzione con l'elenco di valori come argomento usando la * sintassi:

fun1(*l)
# Returns: (1,2,3)
fun1(*['w', 't', 'f'])
# Returns: ('w','t','f')

Ma se non si fornisce un elenco con la lunghezza corrispondente al numero di argomenti:

fun1(*['oops'])
# Raises: TypeError: fun1() missing 2 required positional arguments: 'arg2' and 'arg3'

Imballaggio degli argomenti delle parole chiave

Ora puoi anche comprimere argomenti usando un dizionario. Puoi usare l'operatore ** per dire a Python di decomprimere il dict come valori dei parametri:

d = {
  'arg1': 1,
  'arg2': 2,
  'arg3': 3
}
fun1(**d)
# Returns: (1, 2, 3)

quando la funzione ha solo argomenti posizionali (quelli senza valori predefiniti) è necessario che il dizionario contenga tutti i parametri previsti e non disponga di parametri aggiuntivi, altrimenti si otterrà un errore:

fun1(**{'arg1':1, 'arg2':2})
# Raises: TypeError: fun1() missing 1 required positional argument: 'arg3'
fun1(**{'arg1':1, 'arg2':2, 'arg3':3, 'arg4':4})
# Raises: TypeError: fun1() got an unexpected keyword argument 'arg4'

Per le funzioni che dispongono di argomenti facoltativi, è possibile comprimere gli argomenti come dizionario nello stesso modo:

fun2(**d)
# Returns: (1, 2, 3)

Ma qui puoi omettere i valori, poiché verranno sostituiti con i valori predefiniti:

fun2(**{'arg2': 2})
# Returns: ('a', 2, 'c')

E lo stesso di prima, non puoi dare valori extra che non siano parametri esistenti:

fun2(**{'arg1':1, 'arg2':2, 'arg3':3, 'arg4':4})
# Raises: TypeError: fun2() got an unexpected keyword argument 'arg4'

Nell'uso del mondo reale, le funzioni possono avere sia argomenti posizionali che opzionali, e funziona allo stesso modo:

def fun3(arg1, arg2='b', arg3='c')
    return (arg1, arg2, arg3)

puoi chiamare la funzione solo con un iterable:

fun3(*[1])
# Returns: (1, 'b', 'c')
fun3(*[1,2,3])
# Returns: (1, 2, 3)

o con solo un dizionario:

fun3(**{'arg1':1})
# Returns: (1, 'b', 'c')
fun3(**{'arg1':1, 'arg2':2, 'arg3':3})
# Returns: (1, 2, 3)

oppure puoi utilizzare entrambi nella stessa chiamata:

fun3(*[1,2], **{'arg3':3})
# Returns: (1,2,3)

Attenzione però che non puoi fornire più valori per lo stesso argomento:

fun3(*[1,2], **{'arg2':42, 'arg3':3})
# Raises: TypeError: fun3() got multiple values for argument 'arg2'

Spacchettare gli argomenti della funzione

Quando si desidera creare una funzione che può accettare un numero qualsiasi di argomenti e non imporre la posizione o il nome dell'argomento in fase di "compilazione", è possibile ed ecco come:

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

I parametri *args e **kwargs sono parametri speciali che sono impostati rispettivamente su una tuple e un dict :

fun1(1,2,3)
# Prints: (1, 2, 3) {}
fun1(a=1, b=2, c=3)
# Prints: () {'a': 1, 'b': 2, 'c': 3}
fun1('x', 'y', 'z', a=1, b=2, c=3)
# Prints: ('x', 'y', 'z') {'a': 1, 'b': 2, 'c': 3}

Se si guarda abbastanza codice Python, si scoprirà rapidamente che è ampiamente utilizzato quando si passano gli argomenti a un'altra funzione. Ad esempio se si desidera estendere la classe string:

class MyString(str):
    def __init__(self, *args, **kwarg):
        print('Constructing MyString')
        super(MyString, self).__init__(*args, **kwarg)


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