Segue le regole della sezione Dichiarazioni di assegnazione dalla documentazione,
assignment_stmt ::= (target_list "=")+ (expression_list | yield_expression)
Se target list
è un elenco di target separati da virgole: L'oggetto deve essere un iterabile con lo stesso numero di elementi quanti sono i target nell'elenco target e gli elementi vengono assegnati, da sinistra a destra, ai target corrispondenti.
L'oggetto deve essere una sequenza con lo stesso numero di elementi quanti sono i target nell'elenco dei target e gli elementi vengono assegnati, da sinistra a destra, ai target corrispondenti.
Quindi, quando dici
[] = ""
""
è un iterabile (qualsiasi stringa python valida è un iterabile) e viene decompresso sugli elementi della lista.
Per esempio,
>>> [a, b, c] = "123"
>>> a, b, c
('1', '2', '3')
Dato che hai una stringa vuota e un elenco vuoto, non c'è niente da decomprimere. Quindi, nessun errore.
Ma prova questo
>>> [] = "1"
Traceback (most recent call last):
File "<input>", line 1, in <module>
ValueError: too many values to unpack (expected 0)
>>> [a] = ""
Traceback (most recent call last):
File "<input>", line 1, in <module>
ValueError: need more than 0 values to unpack
Nel [] = "1"
caso, stai cercando di decomprimere la stringa"1"
su un elenco vuoto di variabili. Quindi si lamenta di "troppi valori da decomprimere (previsto 0)".
Allo stesso modo, in [a] = ""
caso cui tu abbia una stringa vuota, quindi niente da decomprimere davvero, ma lo stai decomprimendo su una variabile, il che, di nuovo, non è possibile. Questo è il motivo per cui si lamenta "sono necessari più di 0 valori per decomprimere".
A parte questo, come hai notato,
>>> [] = ()
inoltre non genera errori, perché ()
è una tupla vuota.
>>> ()
()
>>> type(())
<class 'tuple'>
e quando viene decompresso su un elenco vuoto, non c'è nulla da decomprimere. Quindi nessun errore.
Ma quando lo fai
>>> "" = []
File "<input>", line 1
SyntaxError: can't assign to literal
>>> "" = ()
File "<input>", line 1
SyntaxError: can't assign to literal
come dice il messaggio di errore, stai tentando di assegnare una stringa letterale. Che non è possibile. Questo è il motivo per cui ricevi gli errori. È come dire
>>> 1 = "one"
File "<input>", line 1
SyntaxError: can't assign to literal
Interni
Internamente, questa operazione di assegnazione verrà tradotta in UNPACK_SEQUENCE
codice operativo ,
>>> dis(compile('[] = ""', "string", "exec"))
1 0 LOAD_CONST 0 ('')
3 UNPACK_SEQUENCE 0
6 LOAD_CONST 1 (None)
Qui, poiché la stringa è vuota, UNPACK_SEQUENCE
decomprime i 0
tempi. Ma quando hai qualcosa del genere
>>> dis(compile('[a, b, c] = "123"', "string", "exec"))
1 0 LOAD_CONST 0 ('123')
3 UNPACK_SEQUENCE 3
6 STORE_NAME 0 (a)
9 STORE_NAME 1 (b)
12 STORE_NAME 2 (c)
15 LOAD_CONST 1 (None)
18 RETURN_VALUE
la sequenza 123
viene decompressa nello stack, da destra a sinistra. Quindi, la parte superiore della pila sarebbe 1
e la prossima sarebbe 2
e l'ultima sarebbe 3
. Quindi assegna dalla cima dello stack alle variabili dal lato sinistro un'espressione una per una.
A proposito, in Python, è così che puoi eseguire più assegnazioni nella stessa espressione. Per esempio,
a, b, c, d, e, f = u, v, w, x, y, z
questo funziona perché, i valori della mano destra vengono utilizzati per costruire una tupla e quindi verrà decompressa sui valori del lato sinistro.
>>> dis(compile('a, b, c, d, e, f = u, v, w, x, y, z', "string", "exec"))
1 0 LOAD_NAME 0 (u)
3 LOAD_NAME 1 (v)
6 LOAD_NAME 2 (w)
9 LOAD_NAME 3 (x)
12 LOAD_NAME 4 (y)
15 LOAD_NAME 5 (z)
18 BUILD_TUPLE 6
21 UNPACK_SEQUENCE 6
24 STORE_NAME 6 (a)
27 STORE_NAME 7 (b)
30 STORE_NAME 8 (c)
33 STORE_NAME 9 (d)
36 STORE_NAME 10 (e)
39 STORE_NAME 11 (f)
42 LOAD_CONST 0 (None)
45 RETURN_VALUE
ma la classica tecnica di scambio a, b = b, a
utilizza la rotazione degli elementi nella parte superiore della pila. Se hai solo due o tre elementi, vengono trattati con istruzioni speciali ROT_TWO
e ROT_THREE
invece di costruire la tupla e spacchettarli.
>>> dis(compile('a, b = b, a', "string", "exec"))
1 0 LOAD_NAME 0 (b)
3 LOAD_NAME 1 (a)
6 ROT_TWO
7 STORE_NAME 1 (a)
10 STORE_NAME 0 (b)
13 LOAD_CONST 0 (None)
16 RETURN_VALUE
dis('[] = ""')
senza chiamarecompile()
.