Guardate questo codice Python:Stringhe non indicate da dict?
from gc import get_referrers as refs
x = 'x'
d = {x:x}
print(d in refs(x))
Esso stampa False. Questo è strano di per sé, ma diventa molto più strano se si considera quanto segue:
Se x è un numero (int, float, complesso, frazione, decimale) invece di una stringa, esso stampa ancora False. Anche per byte e bytearray. Ma per ogni altro tipo (lavabile se usato come chiave, come tupla o frozenset - ma molti altri, se usato solo come valore), stampa True.
Se d è un qualsiasi altro contenitore (set, elenco, tupla ...) contenente x, stampa True. Solo per un ditt, stampa False. Inoltre, non importa se x è una chiave o un valore, o come sopra, entrambi.
ho pensato in Python ogni oggetto è un riferimento (al contrario di Java, che ha tipi primitivi, o rubino, che valore-tipi piccole INT), ma ora sembra str e int sono tipi pò primitivi, che non sono referenziati. Ma d'altra parte, perché solo in dicts ??
So anche che gli inte da -5 a 256 vengono memorizzati nella cache in CPython (e le stringhe piccole possono essere internate), quindi ha senso non registrarli, poiché non verranno mai eliminati comunque, ma questo funziona per tutti gli interi (e stringhe lunghe) Ho provato, molto più grande di quella gamma.
Qualcuno sa cosa sta succedendo qui?
--- UPDATE ---
più curiose ... sembra datetime. {Datetime, data, ora} classi hanno lo stesso comportamento "senza riferimenti". Ora, conosco una cosa che quelli, AnyStr e Number hanno in comune: i loro hash sono randomizzati con un sale per sessione. Ma questo non rende qualsiasi senso, poiché il comportamento è osservato anche quando questi sono semplicemente valori in dict, non chiavi. E i valori non sono hash. O sono loro?
Interessante, il conteggio dei riferimenti ('sys.getrefcount') aumenta di 2 dopo aver assegnato il dizionario. ma 'get_referrers' restituisce anche False se la chiave e il valore sono diversi (e uno è x), quindi non sembra essere una protezione contro i riferimenti circolari. – cdarke
Sì, era una delle mie ipotesi, ma come hai detto tu non vale perché x non deve essere sia chiave che valore. E altri contenitori (elenchi) possono avere riferimenti circolari, non mostrano questo comportamento. – Veky
BTW, i sintomi sono simili in Python 2.7 e 3.4, i conteggi di riferimento sono numeri totali apparentemente diversi, il che è prevedibile. – cdarke