nach serializability bzw immutabillity fragen

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
Benutzeravatar
Goswin
User
Beiträge: 363
Registriert: Freitag 8. Dezember 2006, 11:47
Wohnort: Ulm-Böfingen
Kontaktdaten:

Ich kann in der Doku nirgendwo finden, wie man fragt ob ein Objekt immutable ist oder nicht. Ich dachte an etwas wie

Code: Alles auswählen

is_immutable(objekt) in Boolean
oder

Code: Alles auswählen

is_subclass(objekt,Immutable) in boolean
aber bisher ohne Erfolg.

Noch interessanter wäre

Code: Alles auswählen

is_serializable(objekt) in boolean
wobei ich voraussichtlich nur sicherstellen werden will, dass ein gepickeltes Objekt keine Speicheradressen enthält.

Kennt jemand etwas zu diesem Thema?
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

Würde das vielleicht helfen:

Code: Alles auswählen

def is_ser(obj):
    try:
        marshal.dumps(obj)
    except: #Weiß nicht, welcher Fehler hier abgefangen gehört...
        return False
    return True
mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Benutzeravatar
Goswin
User
Beiträge: 363
Registriert: Freitag 8. Dezember 2006, 11:47
Wohnort: Ulm-Böfingen
Kontaktdaten:

@mutetella: danke für deinen Hinweis. Herauszufinden, ob er mir tauglich ist, wird einige Zeit brauchen.

"marshal" auszuprobieren scheint interessant zu sein, da "pickle" anscheinend ganz unbrauchbar ist:
DEBUG: is_ser with pickle.dumps(obj)
is_ser((2,3,4)) = True

DEBUG: is_ser with pickle.dumps(obj)
is_ser([[2],[3],[4]]) = True

DEBUG: is_ser with pickle.dumps(obj)
is_ser(range(5)) = True

DEBUG: is_ser with pickle.dumps(obj)
is_ser(range(5)) = True

DEBUG: is_ser with pickle.dumps(obj)
is_ser(meine_Klasse()) = True
wobei das letzte Ergebnis völliger Unsinn ist; es wird nur die Speicheradresse serialisiert und das Objekt kann danach weder identifiziert noch wiederhergestellt werden (oder gilt das etwa nicht mehr für Python3.x?). Dagegen haben wir
DEBUG: is_ser with marshal.dumps(obj)
is_ser((2,3,4)) = True

DEBUG: is_ser with marshal.dumps(obj)
is_ser([[2],[3],[4]]) = True

DEBUG: is_ser with marshal.dumps(obj)
is_ser(list(range(5))) = True

DEBUG: is_ser with marshal.dumps(obj)
is_ser(range(5)) = False

DEBUG: is_ser with marshal.dumps(obj)
is_ser(meine_Klasse()) = False
was schon besser aussieht. Allerdings wird im Handbuch immer von der Benutzung von marshal abgeraten, da sich Python anscheinend die Freiheit nimmt, dieses Modul, rückwärts-inkompatibel zu verändern...
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

Goswin hat geschrieben:(...) es wird nur die Speicheradresse serialisiert und das Objekt kann danach weder identifiziert noch wiederhergestellt werden (...)
Ich glaube, Du hast eine falsche Erwartung bzw. Vorstellung vom Serialisieren. Es handelt sich dabei nicht um einen Vorgang, der Dir ein exaktes Abbild eines bestehenden Zustandes liefert.
Wenn Du also z. B. eine Instanz einer Klasse serialisierst, dann muss die Klassenstruktur (der Code, wenn Du so willst) beim De-serialisieren auch vorhanden sein.

Code: Alles auswählen

class Test(object):
    def __init__(self, foo):
        self.foo = foo

Code: Alles auswählen

>>> t = Test(10)
>>> t.foo
10
>>> pt = pickle.dumps(t)
>>> del t
>>> t = pickle.loads(pt)
>>> t.foo
10
>>> del t
>>> del Test
>>> t = pickle.loads(pt)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.1/pickle.py", line 1363, in loads
    encoding=encoding, errors=errors).load()
AttributeError: 'module' object has no attribute 'Test'
Was hast Du eigentlich genau vor?

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Benutzeravatar
Goswin
User
Beiträge: 363
Registriert: Freitag 8. Dezember 2006, 11:47
Wohnort: Ulm-Böfingen
Kontaktdaten:

mutetella hat geschrieben:Was hast Du eigentlich genau vor?
Unittests erstellen, um meinen Software-Umbau ("Refactoring") zu kontrollieren.

Meine Berechnungen liefern extrem große Ergebnisobjekte, so dass ich mir die Arbeit sparen möchte, deren Attribute per aufwändigen Extracode einzeln zu vergleichen. Wenn ich sie serialisieren kann, dann habe ich grundsätzlich einen langen String, den ich entweder direkt vergleichen kann, oder mit Hilfe der hash-Funktion für Strings auch rekursiv verkürzen kann.

Ich müsste aber vorher sicherstellen, dass ich mit meinem Ergebnisobjekt nicht versehentlich Zeiger auf Speicheraddressen oder sonstigen Unsinn serialisiere, sonst werden meine Unittest-Strings *nie* übereinstimmen.
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

Ok, wir sind nicht mehr weit von dem Punkt entfernt, ab dem ich Dir nicht mehr weiterhelfen kann... :mrgreen:

Aber interessieren würde es mich schon, kannst Du mir vielleicht einmal ein konkretes Beispiel eines solchen Objektes oder eines seiner Attribute geben?

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
BlackJack

@Goswin: Pickles sind nicht eindeutig, soll heissen zwei verschiedene Pickles können beim entpickeln das gleiche Ergebnis haben. Das was in so einem Pickle drin steckt ist im Grunde ein kleines Programm in der „Pickle-Sprache“, das eine äquivalente Datenstruktur zu dem was mal gepickelt wurde erstellen soll. Verschiedene Python-Implementierungen oder auch Versionen einer Implementierung können für die gleichen Strukturen in den Bytes unterschiedliche Pickles erzeugen. Selbst `pickle` und `cPickle` aus der selben Standardbibliothek können das für die selben Daten und das gleiche Protokoll.

So etwas wie „Zeiger“ können in einem Pickle gar nicht drin sein, ausser auf Strukturen die auch innerhalb des Pickles sind, denn sonst könnte man das ja nicht mehr entpickeln. Allerdings wie bei Deinem Beispiel zu sehen Namen von Typen. Da in Python alles irgend wie zusammen hängt, muss man ja auch irgendwo aufhören, sonst hat man am Ende bei jedem Pickle *alle* Objekte drin. :-)

Und laut Beispiel möchtest Du nicht wissen ob Du etwas pickeln kannst, sondern ob Du es auch wieder *ent*pickeln kannst. *Beides* bekommt man im Grunde nur durch ausprobieren heraus.
Benutzeravatar
Goswin
User
Beiträge: 363
Registriert: Freitag 8. Dezember 2006, 11:47
Wohnort: Ulm-Böfingen
Kontaktdaten:

BlackJack hat geschrieben:Pickles sind nicht eindeutig, soll heissen zwei verschiedene Pickles können beim entpickeln das gleiche Ergebnis haben.
...und da dieses Ergebnis wieder ein Objekt wäre und kein String, wäre ich genau da angelangt, wo ich angefangen hätte. Nachträglich fällt mir ein: auch wenn das gepickelte Objekt ein String und kein Pickel-Code *wäre*, dann wäre immer noch nicht gesagt, dass dieser String von Version zu Version nicht verschieden sein kann. Mich auf eine Version festlegen sollte ich nicht, der Unittest wäre bei der nächsten Version unter Umständen wertlos. Ich werde also dazu übergehen, einen hash-Code für meine Ergebnisobjekte zu schreiben, auch wenn das etwas mehr Arbeit ist.
mutetella hat geschrieben:Kannst Du mir vielleicht einmal ein konkretes Beispiel eines solchen Objektes oder eines seiner Attribute geben?
Der Suchbaum einer Branch-and-Bound-Suche nach 20 Suchschritten. So ein B&B-Suchbaum kann nicht nur sehr groß sein, sondern hat auf jedem seiner Knoten auch noch verschachtelte Listen und massenweise andere Attribute. So ein Suchbaum ist natürlich nur ein Zwischenergebnis zur Lösung der Aufgabe, aber für meine Unittest muss ich gerade die Zwischenergebnisse überprüfen, da die Endlösung viel zu wenig über den Code eines einzelnen Moduls aussagt.


:D Vielen Dank allen beiden! :D
anogayales
User
Beiträge: 456
Registriert: Mittwoch 15. April 2009, 14:11

Mal eine kleine Frage nebenbei. Was machst du wenn der Unit Test fehlschlägt? Dann weißt du ja nur, dass es irgendwo eine Diskrepatz gibt, aber nicht notwendigerweise wo. Bei einer so großen Menge an Daten wird dir das doch wenig weiterbringen, oder? Unit Tests sollten doch möglichst konkret geschrieben werden.
Benutzeravatar
Goswin
User
Beiträge: 363
Registriert: Freitag 8. Dezember 2006, 11:47
Wohnort: Ulm-Böfingen
Kontaktdaten:

Die letzten Beiträge passen nicht mehr zum Thementitel; ich antworte im Thema "Hashcodes & Unittests" (weiß aber nicht, wie man einen Link dorthin setzt).
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

BlackJack hat geschrieben:Das was in so einem Pickle drin steckt ist im Grunde ein kleines Programm in der „Pickle-Sprache“, (...)
Gibt es eigentlich eine standarisierte marshal-Struktur? Ähnlich wie json, wobei json z. B. schon mal keinen Unterschied zwischen 'list' und 'tuple' macht. Aber an genau diesen Details scheitert ein solcher Standard wohl, oder?

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Antworten