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.
ich möchte das/die "pickle"-Protokoll(e) von Phyton gerne mit PHP nutzen können, damit man z.B: zwischen den beiden Programmiersprachen besser kommunizieren kann. Nur leider finde ich nirgends eine ausführliche Definition der Protokolle
Aber bei deinem Problem bietet sich eigentlich eher JSON an. Dafuer sollte es eigentlich auch PHP Libs geben. Auch wenn ich nicht verstehe warum man PHP nutzen sollte, wenn man Python haben kann...
Auch wenn ich nicht verstehe warum man PHP nutzen sollte, wenn man Python haben kann...
*G* Genau darauf habe ich gewartet, aber egal
Aber bei deinem Problem bietet sich eigentlich eher JSON an. Dafuer sollte es eigentlich auch PHP Libs geben.
Ja klar gibt es, aber nicht alle Datentypen werden dann sauber übersetzt und zudem verliert man auch noch alle Referenzen, was sich bei größeren Datenmengen schon bemerkbar macht.
Oder man koennte die Pickle-Stacksprache in PHP implementieren. Wobei ich mir nicht sicher bin, ob mitsuhiko nicht genau das schon früher mal gemacht hat.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Wo genau liegt das Problem mit Referenzen? Kannst Du da mal ein Beispiel geben? Würde mich mal interessieren, wie man das ggf. in JSON doch handeln kann.
Alleine die Größe kann's ja nicht sein, denn man sollte JSON gut zippen können.
Hyperion hat geschrieben:Wo genau liegt das Problem mit Referenzen? Kannst Du da mal ein Beispiel geben?
Jede zyklische Datenstruktur kann man nicht einfach so serialisieren. Das betrifft beispielsweise doppelt verkettete Listen oder Bäume der Art Vater->Kinder, Kind->Vater. Da jedes Element auch wieder eine Referenz auf seinen Vorgänger hat, kann ein "dummer" Serialisierungsversuch gar nicht terminieren.
Um solche Datenstrukturen zu serialisieren, muss man die Zyklen entweder manuell lösen (in dem man z.B. im Baum alle Referenzen auf das Vater-Element nullt) oder eben ein Serialisierungsformat entwickeln, welches Referenzen hat.
@Hyperion: Auch Strukturen ohne Zyklen können Probleme bereiten, weil Referenzen durch das serialisieren nach JSON verloren gehen, und damit verhalten sich die Ergebnisse anders:
In [3]: a = [1, 2]
In [4]: b = [a, a]
In [5]: b
Out[5]: [[1, 2], [1, 2]]
In [6]: c = pickle.loads(pickle.dumps(b))
In [7]: c
Out[7]: [[1, 2], [1, 2]]
In [8]: c[0][1] = 42
In [9]: c
Out[9]: [[1, 42], [1, 42]]
In [10]: c = simplejson.loads(simplejson.dumps(b))
In [11]: c
Out[11]: [[1, 2], [1, 2]]
In [12]: c[0][1] = 42
In [13]: c
Out[13]: [[1, 42], [1, 2]]
Es hat ungefähr 15 Minuten gedauert, einen eigenen Serializer zu bauen, der so einfach ist, dass man sicherlich auch ein PHP-Gegenstück bauen kann und der dies kann:
Das { steht für dict, ( für tuple, I für int und S für str. Danach kommen jeweils die Daten. Sequenzen werden mit ; beendet. Das R ist eine Referenz, damit rekursive Datenstrukturen funktionieren. Der Encoder hat 21 Zeilen, der Decoder 26.
Zwei Anmerkungen: Strings mit Single-Quotes und negative Integers mag das Ding nicht, und das Slicing von m.group() könnte man vermeiden, wenn man die Gruppen in der Regex auf den eigentlichen Wert einschränkt. Ach ja, und es dürfte schneller sein, den String nicht nach jedem Match zu slicen, sondern einfach einen Startindex i zu inkrementieren und ihn re.match mitzugeben (dafür braucht es aber ein regex-Objekt).
Hatte nicht bedacht, dass `repr()`von ' auf " wechselt, wenn ein ' im String vorkommt. Das und negative Zahlen werden jetzt erkannt. Für Strings ist der reguläre Ausdruck allerdings immer noch zu trivial, denn er erkennt keine \. Das überlasse ich dem Leser als Übung.
Ansonsten habe ich nach birkenfelds Blick den Code nochmals geändert, weil mir doch 40 Zeilen für den Decoder einfach zu viel waren. Auf Effizienz hatte ich zwar überhaupt nicht geachtet, aber ich denke, das neue Verfahren würde besser performen, wenn einem das wichtig wäre.