Così ho creato una classe personalizzata in Python che supporta l'iterazione usando il metodo __iter__
. Il mio metodo __iter__
è strutturato come un oggetto generatore, utilizzando yield
per assegnare ciascuno dei valori nell'istanza della classe.Chiamare iter() su un'istanza della mia classe non crea una "istantanea" dei suoi valori correnti?
Ho constatato che se dico qualcosa come x = iter(my_instance)
e quindi modificare i dati memorizzati nel mio esempio, se in seguito a creare un elenco di x
, troverò che tale elenco contiene i valori che my_class
ha attualmente, piuttosto rispetto ai valori che aveva quando ho chiamato iter()
.
Quindi la mia domanda è duplice a questo punto. Prima di tutto, è questo che dovrebbe succedere? Se è così, perché funziona così?
Sopra è la cosa principale, ma se vuoi davvero andare oltre, continua a leggere. Ora il motivo per cui sto facendo questa domanda è che ho dovuto creare questa lezione come incarico all'università. Il mio professore ha fornito un programma che eseguirà una serie di test su questa classe che ho creato per darmi una buona idea se l'ho fatto correttamente o meno la prima volta.
Il mio programma passa ogni singolo controllo tranne l'ultimo, che in pratica fa ciò che è descritto sopra. Il problema è che si aspetta che l'elenco creato da una precedente chiamata a iter(my_object)
rifletta solo i valori memorizzati in my_object
nel momento in cui è stato chiamato iter()
. La mia reazione iniziale dopo aver osservato questo aspetto era che il mio professore intendeva ottenere un risultato simile semplicemente chiamando list(my_object)
, ma io sono lo studente qui, quindi sembra molto più probabile che ho semplicemente codificato il mio metodo __iter__
in alcuni molto strani modo, che sta causando questo comportamento. Oppure Python ha cambiato il modo in cui la funzione iter()
funziona di recente?
preferirei non pubblicare il mio codice, dal momento che è per una classe, e che potrebbe tecnicamente essere considerato barare (so che è stupido e inutile, sorry). Tuttavia, posso collegare la specifica, che è giusta here (in particolare parte 1, la classe Bag
).
L'iteratore e la classe utilizzano lo stesso oggetto elenco sottostante per l'archiviazione. Questo è il motivo per cui entrambi vedranno un cambiamento quando si modificano i dati. – Nayuki
Se si desidera "congelare" l'iteratore, è possibile convertirlo esplicitamente in un elenco (o in un altro tipo di dati di consumo). Gli iteratori sono solitamente pigri, il che spiega perché il tuo ha il comportamento descritto. –
Quando si itera su oggetti mutabili (e la tua borsa è mutabile), anche gli iteratori della libreria standard mostreranno lo stesso comportamento: opereranno sull'iterazione nello stato corrente, riflettendo le modifiche. – Cyb3rFly3r