Le manuel Python a ceci à dire à propos de id()
:
Renvoie "l'identité" d'un objet. Il s'agit d'un entier (ou entier long) qui est garanti unique et constant pour cet objet pendant sa durée de vie. Deux objets dont la durée de vie ne se chevauche pas peuvent avoir la même valeur id (). (Note d'implémentation: c'est l'adresse de l'objet.)
Donc en CPython, ce sera l'adresse de l'objet. Aucune garantie de ce type pour aucun autre interpréteur Python, cependant.
Notez que si vous écrivez une extension C, vous avez un accès complet aux internes de l'interpréteur Python, y compris l'accès aux adresses des objets directement.
lifetime
(et que signifie la durée de vieoverlap/not overlap
) dans ce contexte?Vous pouvez réimplémenter la repr par défaut de cette façon:
la source
return object.__repr__(self)
ou même le faireobject.__repr__(obj)
chaque fois que vous en avez besoin au lieu de créer une nouvelle classe__repr__ = object.__repr__
, et n'est pas aussi infaillible, car il existe une variété de situations où cela ne fonctionne pas, par exemple une__getattribute__
implémentation remplacée ou non CPython où l'id n'est pas l'emplacement de la mémoire. Il ne se remplit pas non plus en z, vous devrez donc déterminer si le système est 64 bits et ajouter les zéros si nécessaire.Juste utiliser
la source
id()
@JLTIl y a quelques problèmes ici qui ne sont couverts par aucune des autres réponses.
Tout d'abord,
id
ne renvoie que:En CPython, il s'agit du pointeur vers le
PyObject
qui représente l'objet dans l'interpréteur, qui est la même chose quiobject.__repr__
s'affiche. Mais ce n'est qu'un détail d'implémentation de CPython, pas quelque chose qui est vrai de Python en général. Jython ne s'occupe pas des pointeurs, il traite des références Java (que la JVM représente bien sûr probablement comme des pointeurs, mais vous ne pouvez pas les voir - et vous ne voudriez pas, car le GC est autorisé à les déplacer). PyPy permet à différents types d'avoir différents types deid
, mais le plus général est juste un index dans une table d'objets que vous avez appelésid
sur, ce qui ne sera évidemment pas un indicateur. Je ne suis pas sûr d'IronPython, mais je suppose que cela ressemble plus à Jython qu'à CPython à cet égard. Donc, dans la plupart des implémentations Python, il n'y a aucun moyen d'obtenir ce qui s'y trouverepr
, et cela ne sert à rien si vous l'avez fait.Mais que faire si vous ne vous souciez que de CPython? C'est un cas assez courant, après tout.
Eh bien, tout d'abord, vous remarquerez peut-être que
id
c'est un entier; * si vous voulez cette0x2aba1c0cf890
chaîne au lieu du nombre46978822895760
, vous devrez la formater vous-même. Sous les couvertures, je penseobject.__repr__
qu'en fin de compte, il utiliseprintf
le%p
format de, que vous n'avez pas de Python ... mais vous pouvez toujours le faire:* Dans 3.x, c'est un
int
. Dans 2.x, c'est unint
si c'est assez grand pour contenir un pointeur - ce qui peut ne pas être dû à des problèmes de nombres signés sur certaines plates-formes - et unlong
autre.Y a-t-il quelque chose que vous pouvez faire avec ces pointeurs en plus de les imprimer? Bien sûr (encore une fois, en supposant que vous ne vous souciez que de CPython).
Toutes les fonctions de l' API C prennent un pointeur vers un
PyObject
ou un type associé. Pour ces types associés, vous pouvez simplement appelerPyFoo_Check
pour vous assurer qu'il s'agit bien d'unFoo
objet, puis lancer avec(PyFoo *)p
. Donc, si vous écrivez une extension C,id
c'est exactement ce dont vous avez besoin.Et si vous écrivez du code Python pur? Vous pouvez appeler exactement les mêmes fonctions avec
pythonapi
dectypes
.Enfin, quelques-unes des autres réponses ont été soulevées
ctypes.addressof
. Ce n'est pas pertinent ici. Cela ne fonctionne que pour desctypes
objets commec_int32
(et peut-être quelques objets de type tampon mémoire, comme ceux fournis parnumpy
). Et, même là, cela ne vous donne pas l'adresse de lac_int32
valeur, c'est l'adresse du niveau Cint32
qui sec_int32
termine.Cela étant dit, le plus souvent, si vous pensez vraiment avoir besoin de l'adresse de quelque chose, vous ne vouliez pas d'un objet Python natif en premier lieu, vous vouliez un
ctypes
objet.la source
id
- y compris leur utilisation pour contenir des valeurs mutables dans unseen
ensemble ou uncache
dict - ne dépendent d'aucune façon du fait d'id
être un pointeur, ou liées de quelque manière que ce soit aurepr
. C'est exactement pourquoi ce code fonctionne dans toutes les implémentations Python, au lieu de fonctionner uniquement en CPython.id
pour cela, mais je veux dire que même en java, vous pouvez obtenir l'adresse de l'objet, cela semble étrange, il n'y a aucun moyen dans (C) Python car celui-ci a en fait un gc stable qui ne déplace pas les objets, donc l'adresse reste la mêmeid
fo un objet, que ce soit une adresse ou non. Par exemple, dans PyPy,id
est toujours aussi utile qu'une clé en CPython, même s'il ne s'agit généralement que d'un index dans une table cachée de l'implémentation, mais un pointeur serait inutile, car (comme Java) l'objet peut être déplacé dans Mémoire.id
d'un objet est le pointeur vers l'emplacement de l'objet en mémoire. Donc, si vous avez une utilisation de la valeur du pointeur (ce que vous ne faites presque jamais, comme expliqué également dans la réponse) dans du code spécifique à CPython, il existe un moyen de l'obtenir qui est documenté et garanti de fonctionner.Juste en réponse à Torsten, je n'ai pas pu appeler
addressof()
un objet Python normal. De plus,id(a) != addressof(a)
. C'est en CPython, je ne sais rien d'autre.la source
Avec ctypes , vous pouvez réaliser la même chose avec
Documentation:
Notez que dans CPython, actuellement
id(a) == ctypes.addressof(a)
, maisctypes.addressof
devrait renvoyer l'adresse réelle pour chaque implémentation Python, siEdit : ajout d'informations sur l'indépendance de l'interpréteur des ctypes
la source
TypeError: invalid type
lorsque je l'essaye avec Python 3.4.Vous pouvez obtenir quelque chose qui convient à cet effet avec:
la source
Je sais que c'est une vieille question, mais si vous êtes encore en train de programmer, en python 3 ces jours-ci ... j'ai en fait trouvé que s'il s'agit d'une chaîne, il existe un moyen très simple de le faire:
la conversion de chaîne n'affecte pas non plus l'emplacement en mémoire:
la source
S'il est vrai qu'il
id(object)
obtient l'adresse de l'objet dans l'implémentation CPython par défaut, c'est généralement inutile ... vous ne pouvez rien faire avec l'adresse du code Python pur.Le seul moment où vous pourriez réellement utiliser l'adresse est à partir d'une bibliothèque d'extensions C ... auquel cas il est trivial d'obtenir l'adresse de l'objet puisque les objets Python sont toujours transmis comme des pointeurs C.
la source
ctypes
boîte à outils intégrée dans la bibliothèque standard. Dans ce cas, vous pouvez faire toutes sortes de choses avec l'adresse :)