string zu array

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
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.
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

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.
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

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
[code]#!/usr/bin/env python
import this[/code]
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

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
rogen

danke die zeile hat super funktioniert
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

Hi. Diese Zeile funktioniert aber auch nur solange, wie nur 2 Listen ineinander verschachtelt sind... wirds mehr oder weniger gibts Probleme... :roll:
rogen

für mich ist das in ordnung

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

mfg
HarryH
User
Beiträge: 266
Registriert: Freitag 23. Mai 2003, 09:08
Wohnort: Deutschland

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.
Gruß, Harry
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Wofür nutzt du StringIO? Pickle kann doch durch .dumps() und .loads() direkt mit Strings arbeiten.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
HarryH
User
Beiträge: 266
Registriert: Freitag 23. Mai 2003, 09:08
Wohnort: Deutschland

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?
Gruß, Harry
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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).
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Antworten