Accéder À La Mémoire D'Objet Adresse
Lorsque vous appelez la object.__repr__()
méthode en Python, vous obtenez quelque chose comme ceci arrière:
<__main__.Test object at 0x2aba1c0cf890>
Est-il possible d'obtenir une prise de l'adresse de la mémoire si vous surchargez __repr__()
, d'autres, puis de l'appel super(Class, obj).__repr__()
et regexing cela?
Vous devez vous connecter pour publier un commentaire.
La Python manuel a ceci à dire à propos de
id()
:Donc dans Disponible, ce sera l'adresse de l'objet. Pas de cette garantie, pour tout autre interpréteur Python, cependant.
Notez que si vous avez écrit un C extension, vous avez un accès complet aux données internes de l'interpréteur Python, y compris l'accès aux adresses des objets directement.
lifetime
(et ce que cela signifie pour la durée de vie deoverlap/not overlap
) voir dans ce contexte?Vous pourriez reproduire le défaut repr de cette façon:
return object.__repr__(self)
ou même juste faireobject.__repr__(obj)
chaque fois que vous avez besoin de cela au lieu de faire une nouvelle classe__repr__ = object.__repr__
, et n'est pas aussi infaillible, comme il existe une variété de situations où cela ne fonctionne pas, par exemple, un surdéfini__getattribute__
ou non Disponible de mise en œuvre où l'id n'est pas l'emplacement de la mémoire. Il également ne pas z-remplissage, de sorte que vous devrez travailler si le système est en 64 bits et ajouter des zéros si nécessaire.Suffit d'utiliser
id()
@JLTIl y a quelques problèmes qui ne sont pas couverts par aucune des autres réponses.
D'abord,
id
ne retourne:Dans Disponible, cela arrive à être le pointeur de la
PyObject
qui représente l'objet de l'interprète, qui est la même chose queobject.__repr__
affiche. Mais ce n'est qu'un détail d'implémentation de Disponible, pas quelque chose qui est vrai de Python en général. Jython n'a pas affaire à des pointeurs, il traite en Java références (que la JVM de cours représente probablement que les pointeurs, mais vous ne pouvez pas voir ces et ne le veulent pas, parce que le conseil d'administration est autorisé à déplacer). PyPy permet aux différents types de différents types deid
, mais le plus général est juste un index dans une table d'objets que vous avez appeléid
sur, ce qui n'est évidemment pas un pointeur. Je ne suis pas sûr IronPython, mais je soupçonne que c'est plus comme Jython que comme Disponible à cet égard. Donc, dans la plupart des implémentations de Python, il n'y a aucun moyen d'obtenir tout ce qui apparaissait dansrepr
, et ne sert à rien si vous n'.Mais que faire si vous ne se soucient Disponible? C'est un joli cas le plus courant, après tout.
Eh bien, tout d'abord, vous remarquerez peut-être que
id
est un entier;* si vous voulez que0x2aba1c0cf890
chaîne, au lieu de le nombre46978822895760
, vous allez avoir à le formater vous-même. Sous les couvertures, je croisobject.__repr__
est en fin de compte à l'aide deprintf
's%p
format, que vous n'avez pas de Python... mais vous pouvez toujours le faire:* En 3.x, c'est un
int
. En 2.x, c'est unint
si c'est assez grand pour contenir un pointeur qui n'est peut être pas à cause de signé nombre de questions sur certaines plates—formes-et unlong
autrement.Est-il quelque chose que vous pouvez faire avec ces pointeurs en plus de les imprimer? Assurez-vous (encore une fois, en supposant que vous ne se soucient Disponible).
Tous les C API fonctions prennent un pointeur vers un
PyObject
ou un type associé. Pour ces types, vous pouvez les appelerPyFoo_Check
pour s'assurer qu'il est vraiment unFoo
objet, puis moulé avec(PyFoo *)p
. Donc, si vous êtes à la rédaction d'un C extension, leid
est exactement ce dont vous avez besoin.Que faire si vous êtes l'écriture pure code Python? Vous pouvez appeler exactement les mêmes fonctions avec
pythonapi
dectypes
.Enfin, quelques-uns des autres réponses ont apporté
ctypes.addressof
. Ce n'est pas pertinente ici. Cela ne fonctionne que pourctypes
objets commec_int32
(et peut-être un peu de la mémoire-tampon-comme des objets, comme ceux fournis parnumpy
). Et, même là, il n'est pas de vous donner l'adresse de l'c_int32
valeur, c'est de vous donner l'adresse de la C-niveauint32
que lec_int32
s'enveloppe.Cela étant dit, le plus souvent, si vous pensez vraiment que vous avez besoin de l'adresse de quelque chose, vous ne voulez pas un natif objet Python, en premier lieu, vous vouliez un
ctypes
objet.id
—y compris l'aide pour organiser des valeurs mutables dans unseen
ou d'unecache
dict—ne dépendent pas de toute façon sur leid
étant un pointeur, ou liés de quelque façon à l'repr
. Ce qui est exactement pourquoi ce code fonctionne dans toutes les implémentations de Python, au lieu de travailler uniquement Disponible.id
pour elle, mais je veux dire encore, même en java, vous pouvez obtenir l'adresse de l'objet, semble étrange, il n'y a pas de voie (C)Python depuis que l'on a réellement stable gc, qui ne sera pas déplacer des objets ainsi l'adresse reste la mêmeid
fo un objet, si c'est une adresse ou pas. Par exemple, dans PyPy,id
est toujours aussi utile comme un élément clé dans Disponible, même si il est habituellement juste un index dans certains cachés de la table dans la mise en œuvre, mais un pointeur serait inutile, parce que (comme Java) l'objet peut être déplacé dans la mémoire.id
d'un objet est le pointeur sur l'objet de l'emplacement dans la mémoire. Donc, si vous avez toute utilisation de la valeur du pointeur (qui vous presque jamais le faire, comme il est expliqué dans la réponse) dans Disponible-code spécifique, il est un moyen d'obtenir ce qui est documenté et garanti pour fonctionner.Juste en réponse à Torsten, je n'ai pas pu appeler
addressof()
régulièrement objet python. En outre,id(a) != addressof(a)
. C'est dans Disponible, ne connaissent pas autre chose.Avec ctypes, vous pouvez réaliser la même chose avec
Documentation:
Noter que dans Disponible, actuellement
id(a) == ctypes.addressof(a)
, maisctypes.addressof
doit retourner l'adresse réelle pour chaque Python de mise en œuvre, siModifier: ajout d'informations sur l'interprète de l'indépendance de ctypes
TypeError: invalid type
quand je l'ai essayer avec Python 3.4.Vous pouvez obtenir quelque chose de convenable avec:
Même s'il est vrai que
id(object)
devient l'objet de l'adresse par défaut est Disponible de la mise en œuvre, ce qui est généralement inutile... vous ne pouvez pas ne n'importe quoi avec l'adresse de la pure code Python.Le seul moment où l'on serait en mesure d'utiliser l'adresse est à partir d'un C extension de la bibliothèque... dans ce cas, il est trivial pour obtenir l'adresse de l'objet depuis Python les objets sont toujours passés en tant que C les pointeurs.
ctypes
boîte à outils de la Bibliothèque Standard. Dans ce cas, vous pouvez faire toutes sortes de choses avec l'adresse 🙂Je sais que c'est une vieille question, mais si vous êtes toujours à la programmation en python 3 de ces jours... en fait, j'ai trouvé que si c'est une chaîne de caractères, alors il est vraiment un moyen facile de faire cela:
chaîne de conversion n'a pas d'incidence sur l'emplacement dans la mémoire, soit: