Frage

Wenn Sie die object.__repr__() Methode in Python rufen Sie so etwas wie dieser zurück:

<__main__.Test object at 0x2aba1c0cf890> 

Gibt es eine Möglichkeit, einen Einfluß der Speicheradresse zu erhalten, wenn Sie __repr__() überlasten, andere dann ruft super(Class, obj).__repr__() und regexing es aus?

War es hilfreich?

Lösung

Das Python Handbuch hat dies über id() zu sagen:

  

Gibt die „Identität‚‘ein Objekt.   Dies ist eine ganze Zahl (oder long integer)   die einzigartig sein ist garantiert und   für dieses Objekt konstant während seines   Lebenszeit. Zwei Objekte mit   nicht überlappenden Lebensdauern aufweisen kann das   gleiche ID () Wert. (Umsetzung beachten Sie:   Dies ist die Adresse des Objekts.)

So in CPython, wird dies die Adresse des Objekts sein. Eine solche Garantie für andere Python-Interpreter, though.

Beachten Sie, dass, wenn Sie eine C-Erweiterung schreiben, Sie vollen Zugriff auf die Interna der Python-Interpreter haben, zählt auch der Zugriff auf die Adressen von Objekten direkt.

Andere Tipps

Sie könnten der Standard repr auf diese Weise neu implementieren:

def __repr__(self):
    return '<%s.%s object at %s>' % (
        self.__class__.__module__,
        self.__class__.__name__,
        hex(id(self))
    )

Verwenden Sie einfach

id(object)

Es gibt ein paar Probleme hier, die nicht durch eine der anderen Antworten abgedeckt ist.

Zuerst id nur zurückgibt:

  

die „Identität“ ein Objekt. Dies ist eine ganze Zahl (oder long integer), die für dieses Objekt einzigartig und konstant ist während seiner gesamten Lebensdauer gewährleistet ist. Zwei Objekte mit nicht-überlappenden Lebensdauern können denselben id() Wert haben.


In CPython, geschieht dies der Zeiger auf den PyObject zu sein das stellt das Objekt in dem Interpreter, der die gleiche Sache, die zeigt object.__repr__. Aber das ist nur eine Implementierung Detail von CPython, nicht etwas, das in der Regel gilt für Python ist. Jython befasst sich nicht in Zeiger, es befasst sich in Java Referenzen (die die JVM natürlich wahrscheinlich als Zeiger darstellt, aber Sie können diejenigen-und nicht sehen möchte nicht, weil der GC ist erlaubt ihnen, sich zu bewegen). PyPy können verschiedene Arten verschiedene Arten von id haben, aber das allgemeinste ist nur ein Index in eine Tabelle von Objekten Sie id aufgerufen haben, das ist offensichtlich nicht ein Zeiger sein würde. Ich bin nicht sicher über Ironpython, aber ich würde vermuten, dass es mehr wie Jython ist als wie CPython in dieser Hinsicht. Also, in den meisten Python-Implementierungen, gibt es keine Möglichkeit zu bekommen, was in diesem repr auftauchten, und nichts, wenn du getan hast.


Aber was, wenn Sie kümmern sich nur um CPython? Das ist ein ziemlich häufiger Fall, nachdem alle.

Nun, zuerst, können Sie, dass id bemerken eine ganze Zahl ist; *, wenn Sie möchten, dass 0x2aba1c0cf890 Zeichenfolge statt der Nummer 46978822895760, du gehst, es selbst haben zu formatieren. Unter den Abdeckungen, glaube ich object.__repr__ ist letztlich printf die %p-Format, die Sie nicht von Python haben ... aber Sie können dies immer tun:

format(id(spam), '#010x' if sys.maxsize.bit_length() <= 32 else '#18x')

* In 3.x, es ist ein int. In 2.x ist es ein int wenn das groß genug ist, einen Zeiger-das zu halten, weil signierte Zahl Probleme auf einigen Plattformen-und long sonst möglicherweise nicht ist.

Gibt es etwas, Sie sie mit diesen Zeiger neben drucken kann? Sicher (wieder, vorausgesetzt, Sie sind nur kümmern uns um CPython).

Alle der C API Funktionen übernehmen einen Zeiger auf eine PyObject oder eine verwandte Art. Für den im Zusammenhang Typen können Sie nur PyFoo_Check nennen es wirklich um sicherzustellen, dass ein Foo Objekt ist, dann mit (PyFoo *)p gegossen. Also, wenn Sie eine C-Erweiterung schreiben, die id ist genau das, was Sie brauchen.

Was ist, wenn Sie reinen Python Code schreiben? Sie können genau die gleichen Funktionen aufrufen mit pythonapi von ctypes.


Schließlich haben einige der anderen Antworten gebracht ctypes.addressof . Das ist hier nicht relevant. Dies funktioniert nur für ctypes Objekte wie c_int32 (und vielleicht ein paar Speicher-Puffer ähnlichen Objekte, wie die von numpy zur Verfügung gestellt). Und selbst da, es ist nicht, dass Sie die Adresse des c_int32 Wert zu geben, ist es die Adresse des C-Level-int32 ist zu geben, dass die c_int32 einpackt.

aber sagen, dass mehr als oft nicht, wenn Sie wirklich, dass Sie die Adresse etwas brauchen, nicht wahr eine native Python-Objekt in erster Linie wollen, können Sie eine ctypes Objekt wollte.

Just in Reaktion auf Torsten, ich war nicht in der Lage addressof() in regelmäßigen Python Objekt aufzurufen. Darüber hinaus id(a) != addressof(a). Dies ist in CPython, weiß nicht, was sonst noch.

>>> from ctypes import c_int, addressof
>>> a = 69
>>> addressof(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: invalid type
>>> b = c_int(69)
>>> addressof(b)
4300673472
>>> id(b)
4300673392

Mit ctypes , können Sie die gleiche Sache mit

>>> import ctypes
>>> a = (1,2,3)
>>> ctypes.addressof(a)
3077760748L

Dokumentation:

  

addressof(C instance) -> integer
  Gibt die Adresse der C-Instanz interner Puffer

Beachten Sie, dass in CPython derzeit id(a) == ctypes.addressof(a), aber ctypes.addressof sollte die reale Adresse für jede Python-Implementierung zurückkehren, wenn

  • ctypes wird unterstützt
  • Speicherzeiger sind ein gültiger Begriff.

Bearbeiten : hinzugefügt Informationen über Dolmetscher-Unabhängigkeit von ctypes

Sie können etwas für diesen Zweck geeignet bekommen mit:

id(self)

Während es wahr ist, dass id(object) die Adresse des Objekts wird in der Standard-CPython Implementierung ist dies in der Regel nutzlos ... Sie können nicht tun irgendetwas mit der Adresse von der reinen Python-Code.

Die einzige Zeit, die Sie würde die tatsächlich in der Lage sein zu verwenden Adresse ist aus einer C-Erweiterungsbibliothek ... in diesem Fall ist es trivial ist an die Adresse des Objekts zu erhalten, da Python-Objekte werden immer um als C Zeiger übergeben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top