La documentazione di Python 3.2 s' weakref
di WeakKeyDictionary
e WeakValueDictionary
hanno una nota sulla iterazione di questi contenitori modulo:in modo sicuro l'iterazione di WeakKeyDictionary e WeakValueDictionary
Nota: Attenzione: A causa di un WeakKeyDictionary è costruita su in cima a un dizionario Python, non deve cambiare le dimensioni quando viene iterato su di esso. Questo può essere difficile da garantire per un WeakKeyDictionary perché le azioni eseguite dal programma durante l'iterazione possono far sì che gli elementi nel dizionario svaniscano "per magia" (come effetto collaterale della garbage collection).
Che sembra piuttosto terribile come una specifica del comportamento di questi contenitori. Soprattutto quando si esegue un codice che usa il garbage collector di CPython (quando si usano strutture dati che contengono un ciclo) o si utilizza un'altra implementazione Python (ad esempio Jython), allora sembra che non ci sia un modo sicuro per iterare su queste raccolte.
Come posso eseguire un'iterazione sicura su queste raccolte quando il garbage collector può cancellare i riferimenti in qualsiasi punto del mio programma? Avere una soluzione per CPython è la mia priorità, ma sono interessato anche al problema di altre implementazioni.
È forse un modo sicuro per scorrere su un WeakKeyDictionary?
import weakref
d = weakref.WeakKeyDictionary()
...
for k, v in list(d.items()):
...
Perché il tuo primo esempio non sarebbe sicuro? L'elenco conterrà forti riferimenti a ogni chiave e valore e durante l'ultima iterazione, 'k' e' v' mantengono forti riferimenti agli oggetti a cui sono interessato. Quindi la lista può essere raccolta inutilmente prima che l'ultima iterazione termini. È giusto? – Feuermurmel
È come dire che 'per k, v in d.items()' è sicuro, perché 'k' e' v' contengono riferimenti forti agli oggetti.L'iterazione non è sicura se, all'interno del ciclo for, esiste la possibilità di eliminare 'k' e' v'. Per compiti abbastanza semplici, iterare su 'WeakKeyDictionary' dovrebbe essere sicuro. – Bakuriu
Probabilmente sto fraintendendo qualcosa, ma come possono essere cancellati gli oggetti 'k' e' v'? Finché queste variabili sono in ambito e non sono nascoste, gli oggetti di riferimento sono sicuri. O stai parlando di rimuovere tutti i riferimenti forti a quegli oggetti durante l'ultima iterazione? Ciò cambierebbe il dizionario, ma non sarebbe pericoloso perché il dizionario non è accessibile dopo l'iterazione è iniziata. Puoi dare un esempio di cosa potrebbe andare storto durante l'ultima iterazione? – Feuermurmel