Wie "pickle"t man Singletons?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Sonntag 5. Oktober 2008, 09:45

Kann ich ein Objektnetz "pickle"n, welches Singletons enthält? Diese werden bei naïver Anwendung natürlich ebenfalls gespeichert und beim Einlesen dann erneut und mit anderer Identität angelegt.

Ich habe folgendes gebaut, einen Hack des Pickle-Moduls für C-Typen nutzend. Doch auch hier meine übliche Frage: Geht es einfacher?

Code: Alles auswählen

def pickle_dump(obj, f, singletons=()):
    singletons = dict((id(obj), str(i)) for i, obj in enumerate(singletons))
    p = pickle.Pickler(f)
    if singletons:
        p.persistent_id = lambda obj: singletons.get(id(obj))
    p.dump(obj)

def pickle_load(f, singletons=()):
    p = pickle. Unpickler(f)
    if singletons:
        p.persistent_load = lambda pid: singletons[int(pid)]
    return p.load()
Stefan
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Sonntag 5. Oktober 2008, 10:05

Naja, unter Python nutzt man statt Singleton eher das Borg-Pattern, von daher kann man dann beliebig viele Instanzen der Klasse haben.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Sonntag 5. Oktober 2008, 10:23

Tut man das? Damit verliere ich aber die einzige Eigenschaft, die ich haben will: Das ich mit "==" (ein "is" muss es ja gar nicht sein) prüfen kann, ob ich ein bestimmtes Objekt habe. Klassen in Python sind ja auch Singletons und ich wollte meine eben auch für eine Klassifizierung benutzen.

Da kann ich dann auch gleich eine eigene "__eq__"-Methode schreiben und nur noch Werte, aber keine Objekte (Objekt = Zustand + Verhalten + Identität), benutzen. Missfällt mir irgendwie, auch wenn Alex Martelli wahrscheinlich schon weiß, wovon er redet.

Stefan
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Sonntag 5. Oktober 2008, 10:40

sma hat geschrieben:Tut man das?
Schau dir doch dieses Snippet (plus Diskussion, die für dich wohl interessanter ist als der Code an sich) an, das ist das Snippet was zu Kapitel 5.23 (1. Ausgabe) bzw 6.16 (2. Ausgabe) im Python-Cookbook führte.

Wenn es dich interessiert, kann ich Auszüge aus der Diskussion im Buch posten.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Sonntag 5. Oktober 2008, 11:15

Leonidas hat geschrieben:Schau dir doch dieses Snippet (plus Diskussion, die für dich wohl interessanter ist als der Code an sich) an
Die Implementierung hatte ich mir angeschaut und daher ja bemängelt -- wie auch jemand in der Diskussion -- dass es kein Singleton ist, weil es die Identität nicht bewahrt und angemerkt, dass die Identität das ist, was ich haben wollte.

Ich bemerke jetzt, dass mein Begriff Singleton irreführend war. Ich will nicht nur ein Exemplar einer Klasse, sondern ich habe schon mehrere Exemplare dieser Klasse, aber jedes dieser will ich noch einmal haben und damit aus dem Pickle-Prozess rausnehmen, damit es nicht dupliziert wird. Daher passt auch das Borg-Entwurfsmuster nicht, da es dieses Problem nicht löst.

Vielleicht reicht aber auch einfach dies (zusammen mit dem Verbot von "is" und "is not"):

Code: Alles auswählen

class Kind:
  def __init__(self, kind, ...):
    self.kind = kind; ...
  def __cmp__(self, other):
    return cmp(self.kind, other.kind) if self.__class__ == other.__class__ else cmp(id(self), id(other))
Stefan
Antworten