Seite 1 von 1
Objekte abspeichern
Verfasst: Sonntag 5. Juni 2022, 15:09
von Loster_Paddel
Hallo,
wenn ich Objekte erstelle, habe ich ja eine Speicheradresse aus dem Arbeitsspeicher, in dem das Objekt liegt. Was mache ich jetzt, wenn ich dieses Objekt richtig abspeichern möchte um es beispielsweise das nächste mal wiederzuverwenden? Zum Beispiel in eine json Datei. Eine Liste könnte ich ja ganz einfach abspeichern, aber wie sieht es aus, wenn ich nur diese Adresse habe? Der Arbeitsspeicher wird ja wieder gelehrt...
Re: Objekte abspeichern
Verfasst: Sonntag 5. Juni 2022, 15:23
von pillmuncher
Du hast keine Adresse eines Objekts im Arbeitsspeicher. Python ist nicht C.
Du könntest je eine Funktion definieren, die aus einem Objekt eine dict-Repräsentation erzeugt, und eine die aus einer entsprechenden dict-Repräsentation ein Objekt erzeugt, und diese Funktionen dann verwenden. Das Umwandeln eines dicts in einen JSON-String ist mittels des json-Moduls aus der Standardbibliothek trivial.
Re: Objekte abspeichern
Verfasst: Sonntag 5. Juni 2022, 16:50
von __blackjack__
@Loster_Paddel: Übrigens selbst wenn das wie C wäre und man tatsächlich die Speicheradressen von Objekten hätte, könnte man die Speicherinhalte nicht einfach so in eine Datei speichern, denn die Bestandteile eines Objektes sind liegen ja wieder als Speicheradressen und man kann wenn man das wieder laden will, nicht garantieren, dass diese Speicherbereiche dann nicht schon von anderen Objekten belegt sind.
Falls Du über das `pickle`-Modul stolpern solltest, eine kleine Warnung: Das sieht auf den ersten Blick superpraktisch aus, hat aber seine Tücken, weil die gespeicherten Daten von der Package-Struktur abhängig ist und auch Probleme bei Code-Änderungen machen können, denn es werden nur die Daten gespeichert und nicht der Code. Und die Datentypen zu den Daten werden als voll qualifizierte Namen gespeichert. Das Modul ist praktisch für die Datenübertragung oder kurzfristiges speichern von aktuellen Daten, beispielsweise in einem Cache, aber nicht für die langfristige Speicherung von Daten zu empfehlen.
Re: Objekte abspeichern
Verfasst: Sonntag 5. Juni 2022, 17:03
von Loster_Paddel
Okay und was ist dann das genau?:
__main__.Moebel object at 0x000002B4430F9FD0>
Wenn es nicht die Adresse fürn Speicher ist...
Und danke erstmal. Das stimmr pickle hab ich schon mal gesehen. Werde mich dann erstmal in die dict-Repräsentation einlesen müssen. Es ist auch noch nicht wtwas was ich bisher gebraucht habe, interessiert mich nur, weil es ja nur eine Frage der Zeit ist, bis man irgendwelche Spieler und damit Objekte abspeichern muss...
Re: Objekte abspeichern
Verfasst: Sonntag 5. Juni 2022, 17:18
von sparrow
Grundsätzlich ist das ein Hinweis darauf, das die Klasse keine __str__ bzw __repr__ Funktion besitzt:
Code: Alles auswählen
class SampleClass():
def __init__(self, name):
self.name = name
class SampleClassWithRepr():
def __init__(self, name):
self.name = name
def __repr__(self):
return f"<{self.__class__}: {self.name}>"
def main():
ham = SampleClass("Ham")
print(ham)
spam = SampleClassWithRepr("Spam")
print(spam)
if __name__ == "__main__":
main()
Ergibt hier auf dem System:
Code: Alles auswählen
<__main__.SampleClass object at 0x000001DBB25FAA00>
<<class '__main__.SampleClassWithRepr'>: Spam>
Und dass du eine Instanz dieser Klasse hast.
Re: Objekte abspeichern
Verfasst: Sonntag 5. Juni 2022, 18:12
von narpfel
@Loster_Paddel: Die lange Hexzahl im Rückgabewert von `object.__repr__` ist die `id` des Objektes, keine Speicheradresse. Zum Beispiel sieht das bei mir so aus:
Code: Alles auswählen
>>>> object.__repr__(42)
'<int object at 0x00000000000002a1>'
>>>> id(42)
673
>>>> hex(id(42))
'0x2a1'
Da wird sehr schnell klar, dass das nicht die Speicheradresse sein kann, weil 673 erstens nicht durch 8 teilbar ist und zweitens die Adresse 673 gar nicht dem Prozess gehört, in dem ich das ausgeführt habe:
Code: Alles auswählen
$ cat /proc/16334/maps
55d8ba394000-55d8ba395000 r--p 00000000 00:18 27294921 /opt/pypy3/bin/pypy3
[... viele Speicherbereiche, nach Adresse sortiert ...]
7ffc9f40a000-7ffc9f42c000 rw-p 00000000 00:00 0 [stack]
7ffc9f4ec000-7ffc9f4f0000 r--p 00000000 00:00 0 [vvar]
7ffc9f4f0000-7ffc9f4f2000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0 [vsyscall]
0x55d8ba394000 ist die kleinste Adresse, die der Prozess benutzen darf.
Die Eigenschaften der `id` sind:
Dokumentation zu `id` hat geschrieben:
Return the “identity” of an object. This is an integer which is guaranteed to be unique and constant for this object during its lifetime. Two objects with non-overlapping lifetimes may have the same id() value.
Nicht mehr, nicht weniger. Insbesondere steht da nichts von „Speicheradresse“.
Re: Objekte abspeichern
Verfasst: Sonntag 5. Juni 2022, 18:25
von __blackjack__
Ich habe es mal etwas angepasst, so dass es rückwärtskompatibel zu Python 2.7 ist und man es mit Jython ausführen kann:
Code: Alles auswählen
#!/usr/bin/env python3
class SampleClass(object):
def __init__(self, name):
self.name = name
class SampleClassWithRepr(object):
def __init__(self, name):
self.name = name
def __repr__(self):
return "<{0.__class__.__name__}: {0.name}>".format(self)
def main():
ham = SampleClass("Ham")
print(ham)
spam = SampleClassWithRepr("Spam")
print(spam)
if __name__ == "__main__":
main()
Testlauf mit CPython:
Code: Alles auswählen
<__main__.SampleClass object at 0x7fe50658cd50>
<SampleClassWithRepr: Spam>
Testlauf mit PyPy
Code: Alles auswählen
<__main__.SampleClass object at 0x00007fa8e2cfdda8>
<SampleClassWithRepr: Spam>
Testlauf mit Jython:
Code: Alles auswählen
<__main__.SampleClass object at 0x2>
<SampleClassWithRepr: Spam>
Bei Jython sieht man deutlich, dass man sich nicht darauf verlassen kann, dass in dem Text etwas steht das eine Speicheradresse ist oder sein könnte, denn wenn man ein weiteres Objekt nach `ham` angelegt hätte, stünde bei dem dort 0x3. Und Objekte sind ganz sicher nicht 1 Byte gross. Es ist nicht einmal sicher, dass dort überhaupt eine Nummer steht, oder das die Hexadezimal angegeben ist, oder eben auch nicht ob das eine Speicheradresse ist oder nicht. Die Darstellung ist Implementierungsdetail. Das einzige was die Dokumentation wirklich ”garantiert”, ist das es entweder eine Zeichenkette ist, mit der man (wahrscheinlich) das Objekt in einem Quelltext schreiben könnte, oder das es in ”spitze Klammern” eingefasst ist und das Objekt in einer Form darstellt, die bei der Fehlersuche nützlich sein kann.
Die Grundimplementierung von `object` in CPython hat den Typnamen und die `id()` als Hex-Zahl in spitzen Klammern. Und die `id()` ist irgendeine Zahl die das Objekt zu einem gegebenen Zeitpunkt eindeutig identifiziert. Das *kann* eine Speicheradresse sein. Aber auch eine künstliche ID wie bei Jython. Was auch immer es ist, man sollte sich nicht auf mehr verlassen, als das der Wert eindeutig ist.
Re: Objekte abspeichern
Verfasst: Sonntag 5. Juni 2022, 18:33
von narpfel
__blackjack__ hat geschrieben: Sonntag 5. Juni 2022, 18:25
Was auch immer es ist, man sollte sich nicht auf mehr verlassen, als das der Wert eindeutig ist.
Nicht mal das: Man darf sich nur auf Eindeutigkeit verlassen, wenn die Objekte, deren IDs man vergleicht, paarweise überlappende Lebenszeiten haben.