Seite 1 von 1

string zu array

Verfasst: Donnerstag 16. September 2004, 11:12
von rogen
ich habe zwei programme die mittles socket kommunizieren

anscheinend kann man nur strings durch den steam schicken.
ich habe den array in einen string umgewandelt


das problem ist ich kann ihn nicht zurückwandeln
mein string sieht so aus "[[1,2,3,4,1,2],[4,5,3,2],[7,5,3,1],[31,42,35,42]]"
mit split geht es auch nicht.

Verfasst: Donnerstag 16. September 2004, 11:44
von Milan
Hi. Weißt du, dass es in Python bei allen Datentypen eine Philosophie sein sollte, dass gilt eval(repr(obj)) == obj ? Sprich, mit repr erzeugt man einen String, der das Objekt obj darstellt und dabei soll gelten, dass wenn man diesen String an eval übergibt man wieder obj erhält. Dies geht zwar für alle Builtin Datentypen (also in deinem Fall), aber Vorsicht:
- sobald eigene Klassen in die Umwandlung einbezogen werden und diese keine eigene Methode __repr__ besitzen greift Python zur Standartdarstellung, welche dann meist nur den Namen von obj und den Adressbereich enthält. Dies kann auf der anderen Seite des Sockets nicht erkannt werden.
- es könnten von anderen Programmen Daten an den Socket gesendet werden, die dieser dann mittels eval auswerten will (direkter Interpreteraufruf !!!). Das kann mitunter eine Sicherheitslücker darstellen.

Besser wäre es sich klar zu sein was gesendet wird und danach ein eigenes Protokoll aufzubauen. Wenn du also Listen mit Zahlen verschickst, die beliebig ineinander verschachtelt sind, kannst du diese auch wieder "demontieren", indem du von links und von rechts nach eckigen Klammern suchst und damit feststellst wo eine Unterliste beginnt. Gibt eine keine Solche kannst du die Daten mittels split aufteilen und in Zahlen konvertieren.

Verfasst: Donnerstag 16. September 2004, 12:34
von Dookie
Hi rogen,

alternativ, zum selber zerlegen und wieder zusammenfügen von Listen kannst du die auch in ein xml umwandeln und über den socket verschicken. Ist bei listen, die nicht nur einen Datentyp enthalten sicher eine elegenate Lösung.


Gruß

Dookie

Verfasst: Donnerstag 16. September 2004, 13:05
von mawe
Hi!

Das Zurückverwandeln in ein array geht eigentlich ganz leicht :wink:

Code: Alles auswählen

x = "[[1,2,3,4,1,2],[4,5,3,2],[7,5,3,1],[31,42,35,42]]"
y = [[int(j) for j in i.split(",")] for i in x.strip("[]").split("],[")]
Gruß, mawe

Verfasst: Donnerstag 16. September 2004, 15:26
von rogen
danke die zeile hat super funktioniert

Verfasst: Donnerstag 16. September 2004, 16:32
von Milan
Hi. Diese Zeile funktioniert aber auch nur solange, wie nur 2 Listen ineinander verschachtelt sind... wirds mehr oder weniger gibts Probleme... :roll:

Verfasst: Donnerstag 16. September 2004, 16:41
von rogen
für mich ist das in ordnung

später werde ich mich um xml bemühen.

mfg

re:

Verfasst: Dienstag 12. Juli 2005, 07:06
von HarryH
Hi,

Bei mir funktioniert es auch mit cPickle und cStringIO gut.

Funktion zum Setzen eines Objekts als pickle-String:

Code: Alles auswählen

import cPickle
from cStringIO import StringIO
def SetObjekt(obj):
    """ Set the sending objekt as pickle string for transfer """
    s = StringIO()
    cPickle.dump(obj, s, 2)
    data = s.getvalue()
    s.close()
    return data
Funktion zum Zurückwandeln eines pickle-Strings in das Objekt:

Code: Alles auswählen

def GetObjekt(pickle_string):
    """ Return the pickle string as real objekt """
    s = StringIO(pickle_string)
    s.seek(0)
    data = cPickle.load(s)
    s.close()
    return data
Evtl. auftretende Fehler können mit try/except abgefangen werden.

Verfasst: Dienstag 12. Juli 2005, 08:52
von Leonidas
Wofür nutzt du StringIO? Pickle kann doch durch .dumps() und .loads() direkt mit Strings arbeiten.

re:

Verfasst: Dienstag 12. Juli 2005, 09:45
von HarryH
Hi ,

Leonidas, du hast vollkommen recht. Wie sagt man so schön: "Wer lesen kann ist klar im Vorteil!" :oops:

Ich habe mich noch nie mit loads und dumps beschäftigt, deswegen vielen Dank für diesen brauchbaren Hinweis.
Die benötigte Zeit für die cStringIO- oder die loads/dumps- Lösung ist allerdings genau die gleiche.

Die Funktionen würden dann folgendermaßen aussehen:

Code: Alles auswählen

def SetObjekt(obj):
    """ Set the sending objekt as pickle string for transfer """
    data = cPickle.dumps(obj, 2)
    return data

def GetObjekt(pickle_string):
    """ Return the pickle string as real objekt """
    data = cPickle.loads(pickle_string)
    return data
Man könnte natürlich auch direkt auf die cPickle-Funktionen zugreifen.

Aber mal noch eine andere Frage:
Was haltet ihr von cPickle in solchen Situationen?

Re: re:

Verfasst: Dienstag 12. Juli 2005, 10:29
von Leonidas
HarryH hat geschrieben:Aber mal noch eine andere Frage:
Was haltet ihr von cPickle in solchen Situationen?
Ich finde Pickle (und damit auch cPickle was praktisch das gleiche ist) für sehr praktisch, wenn es darum geht dass die Daten eines Programmes auch nach dem beenden erhalten bleiben und wieder geladen werden können. Vorteil ist, dass damit vieles serialisiert werden kann und das das sehr leicht geht. Der Nachteil ist halt, dass nur Python das lesen kann, also wenn es ein anderes Programm oder der User lesen soll, verwende ich lieber YAML (oder JSON). Eine andere Möglichkeit wäre noch in XML zu serialisieren (gibt ja genug fertige Lösungen), jedoch reicht mir YAML meist vollkommen (XML würe ich nur nehmen, wenn ich es durch XSL-Transformationen jagen möchte.. tue ich aber nicht).