Sembra a_list sarebbe ancora inizializzato solo una volta
"inizializzazione" non è qualcosa che accade a variabili in Python, perché le variabili in Python sono solo nomi. "inizializzazione" avviene solo per oggetti, e viene eseguita tramite il metodo della classe '__init__
.
Quando si scrive a = 0
, questo è un compito. Questo significa che "a
deve fare riferimento all'oggetto che è descritto dall'espressione 0
". Non è inizializzazione; a
può nominare qualsiasi altro tipo in qualsiasi momento successivo e ciò accade come conseguenza dell'assegnazione di qualcos'altro a a
. L'assegnazione è solo un incarico. Il primo non è speciale.
Quando si scrive def good_append(new_item, a_list=None)
, non è "inizializzato" a_list
. Sta configurando un riferimento interno a un oggetto, il risultato della valutazione di None
, in modo che quando viene chiamato good_append
senza un secondo parametro, tale oggetto viene assegnato automaticamente a a_list
.
significa a_list ottiene solo ripristinare [] sulla prima invocazione
No, a_list
viene impostata su []
ogni volta che a_list
è None
per cominciare. Cioè, quando None
viene passato esplicitamente o l'argomento è omesso.
Il problema si verifica perché []
l'espressione[]
è solo valutati volta in questo contesto. Quando viene compilata la funzione, viene valutato []
, viene creato un oggetto elenco specifico - che risulta essere vuoto per l'avvio - e tale oggetto viene utilizzato come predefinito.
Come viene pulito a_list
ogni volta che si esegue good_append
?
Non funziona. Non ha bisogno di essere.
Sapete come si descrive il problema con "argomenti predefiniti mutabili"?
None
non è modificabile.
Il problema si verifica quando si modifica l'oggetto che il parametro ha come predefinito.
a_list = []
non modifica l'oggetto a_list
precedentemente indicato. Non può; oggetti arbitrari non possono magicamente trasformarsi sul posto in liste vuote. a_list = []
significa "a_list
deve smettere di fare riferimento a ciò a cui si riferiva in precedenza e iniziare a fare riferimento a []
". L'oggetto precedentemente denominato non è stato modificato.
Quando la funzione è compilata e uno degli argomenti ha un valore predefinito, tale valore - un oggetto - viene inserito nella funzione (che è anch'essa un oggetto!). Quando scrivi un codice che muta un oggetto, l'oggetto muta. Se l'oggetto a cui si fa riferimento è l'oggetto infornato nella funzione, si trasforma ancora in mutazione.
Ma non è possibile modificare None
. È immutabile.
È possibile modificare []
. È una lista e le liste sono mutabili. L'aggiunta di un elemento a un elenco modifica l'elenco.
Grazie mille; la frase "ciò che accade quando si chiama' f() 'è implicito' x = f.func_defaults [0] '" è stato fondamentale per la mia comprensione. –
... così tanto che sto cambiando idea, di nuovo, e contrassegnando questo come la risposta corretta. –