2015-09-24 21 views
6

Capisco che il python incorporato id() restituisca un ID che è unico per la durata di un oggetto. Gli oggetti con vite non sovrapposte, ho capito, possono finire con lo stesso ID. Comunque, sto cercando di capire questo comportamento piuttosto confusa:Intervalli id ​​ripetibili su oggetti python

>>> id(matplotlib.image.BboxImage.set_cmap) 
4424372944 
>>> id(numpy.ma.core.MaskedArray.sum) 
4424372944 

E infatti su più istanze di interprete, il comportamento è ripetibile:

Mac:~$ python2.7 -c "import matplotlib.image; import numpy; print id(matplotlib.image.BboxImage.set_cmap), id(numpy.ma.core.MaskedArray.sum)" 
4343186208 4343186208 
Mac:~$ python2.7 -c "import matplotlib.image; import numpy; print id(matplotlib.image.BboxImage.set_cmap), id(numpy.ma.core.MaskedArray.sum)" 
4521153312 4521153312 
Mac:~$ python2.7 -c "import matplotlib.image; import numpy; print id(matplotlib.image.BboxImage.set_cmap), id(numpy.ma.core.MaskedArray.sum)" 
4358591264 4358591264 
Mac:~$ python2.7 -c "import matplotlib.image; import numpy; print id(matplotlib.image.BboxImage.set_cmap), id(numpy.ma.core.MaskedArray.sum)" 
4389970720 4389970720 

sembra che matplotlib.image.BboxImage.set_cmap e numpy.ma.core.MaskedArray.sum ottenere sempre lo stesso ID l'un l'altro, anche attraverso diverse instazzioni dell'interprete python.

Ora ho capito che questo è coerente con i documenti per id() poiché questi due oggetti vengono creati dinamicamente quando vi si accede e quindi avranno effettivamente una durata non sovrapposta. Ma perché quei due oggetti non correlati finiscono sempre con lo stesso ID?

(questa domanda è diverso da Object methods of same class have same id? perché qui mi chiedo perché questo è ripetibile su più istanze di interprete, piuttosto che semplicemente uno scontro id spurio su oggetti con tempi di vita non sovrapposti.)

risposta

6

Questo sarà vero di qualsiasi metodo di istanza, che è il tipo di entrambi gli oggetti che si stanno testando. Ogni volta che si accede al descrittore, viene creato un nuovo oggetto instancemethod. Poiché non si sta salvando un riferimento al metodo appena creato, è possibile effettuare la garbage collection non appena id restituisce, e apparentemente viene raccolto prima della prossima chiamata a id, quindi è possibile riutilizzare la stessa posizione di memoria.

Questo comportamento può essere visto in un altro modo:

>>> x = matplotlib.image.BboxImage.set_cmap 
>>> y = matplotlib.image.BboxImage.set_cmap 
>>> id(x) == id(y) 
False 

x e y sono riferimenti a due oggetti distinti, poiché riferimento set_cmap crea un nuovo oggetto instancemethod ogni volta.