Vous avez utilisé id()
mauvais. id([])
prend l'identifiant mémoire d'un objet qui est jeté immédiatement . Après tout, plus rien ne s'y réfère une fois id()
en a fini avec elle. Donc la prochaine fois que vous utiliserez id([])
Python y voit une opportunité de réutiliser la mémoire et, ô surprise, ces adresses sont bien les mêmes.
Cependant, il s'agit d'un détail d'implémentation, sur lequel vous ne pouvez pas compter, et il ne sera pas toujours possible de réutiliser l'adresse mémoire.
Notez que id()
les valeurs sont uniquement uniques pendant toute la durée de vie de l'objet , voir le documentation :
Il s'agit d'un nombre entier qui est garanti unique et constant pour cet objet pendant sa durée de vie. Deux objets dont les durées de vie ne se chevauchent pas peuvent avoir la même valeur. id()
valeur.
(C'est moi qui souligne en gras).
Ce id(list())
ne peut pas réutiliser l'emplacement mémoire est probablement dû aux mutations supplémentaires du tas causées par le fait de pousser la trame actuelle sur la pile pour appeler une fonction, puis de la sortir à nouveau lorsque la fonction list()
l'appel revient.
Les deux sites []
y list()
produire un nouveau objet liste vide ; mais vous devez d'abord créer des références à ces listes séparées (ici a
y b
) :
>>> a, b = [], []
>>> a is b
False
>>> id(a) == id(b)
False
>>> a, b = list(), list()
>>> a is b
False
>>> id(a) == id(b)
False
La même chose se produit lorsque vous avez utilisé [].__repr__
. L'interpréteur interactif Python a un nom global spécial, _
que vous pouvez utiliser pour faire référence au dernier résultat produit :
>>> [].__repr__
<method-wrapper '__repr__' of list object at 0x10e011608>
>>> _
<method-wrapper '__repr__' of list object at 0x10e011608>
Cela crée une référence supplémentaire, donc le __repr__
et, par extension, la liste vide que vous avez créée pour elle, sont toujours considérés comme actifs . L'emplacement mémoire n'est pas libéré et n'est pas disponible pour la prochaine liste que vous créez.
Mais l'exécution [].__repr__
à nouveau, Python lie maintenant _
à ce nouvel objet méthode. Tout à coup, le précédent __repr__
n'est plus référencée par quoi que ce soit et peut être libérée, tout comme l'objet liste.
La troisième fois que vous exécutez [].__repr__
le premier emplacement mémoire est à nouveau disponible pour être réutilisé, c'est ce que fait Python :
>>> [].__repr__ # create a new method
<method-wrapper '__repr__' of list object at 0x10e00cb08>
>>> _ # now _ points to the new method
<method-wrapper '__repr__' of list object at 0x10e00cb08>
>>> [].__repr__ # so the old address can be reused
<method-wrapper '__repr__' of list object at 0x10e011608>
Vous ne créez jamais plus de deux listes ; la précédente (toujours référencée par _
) et celui en cours. Si vous voulez voir plus d'emplacements mémoire, utilisez des variables pour ajouter une autre référence.