Seite 1 von 1

Mehrfache Zuweisung mit verschiedenen Typen

Verfasst: Montag 1. Dezember 2008, 17:34
von ede
hallo leute, habe folgendes Problem: ich lese aus einer textdatei einen datensatz in string-form aus, der jetzt in eine klasse umgewandelt werden soll, das könnte bspw. so aussehen:

Code: Alles auswählen

class Address:
  def __init__(self, dataset):
     self.__name, self.__street, self.__house = dataset.split('|')

dataset = "maier|lerchenweg|15" #stammt aus datei
a = Address(dataset)
wie der titel schon sagt und zeile 4 zeigt: der zerlegte string (also die liste) soll an variablen mit verschiedenen typen zugewiesen werden (str und int). dass das so nicht funktionieren kann leuchtet ein; kann man die werte trotzdem irgendwie auf einen schlag zuweisen, z.b. mit regex (kenne mich damit leider fast nicht aus)?

Vielen Dank für Eure Vorschläge 8)

Verfasst: Montag 1. Dezember 2008, 17:38
von BlackVivi
Wozu muss diese 15'n int sein?... Musst du damit rechnen? Ich würd's einfach'n String lassen.

Verfasst: Montag 1. Dezember 2008, 17:45
von derdon
Du kannst das zwar nicht in einem Rutsch machen, aber so:

Code: Alles auswählen

self.house = int(self.house)

Code: Alles auswählen

In [10]: dataset = "maier|lerchenweg|15"

In [11]: name, street, house = dataset.split("|")

In [12]: house
Out[12]: '15'

In [13]: house = int(house)

In [14]: house
Out[14]: 15
War dir wahrscheinlich schon vorher klar, aber eine Zeile mehr is ja auch nicht schlimm :lol:

Verfasst: Montag 1. Dezember 2008, 17:56
von ede
BlackVivi hat geschrieben:Wozu muss diese 15'n int sein?... Musst du damit rechnen?
Bei dem beispiel isses wirklich egal, aber die datensätze bestehen insgesamt aus mehreren int's und es soll möglich sein, die datensätze anhand dieser int's zu sortieren/gruppieren und in eine reihenfolge zu bringen. strings kann man zwar auch der größe nach ordnen aber das halte ich für eine unschöne lösung
derdon hat geschrieben:Du kannst das zwar nicht in einem Rutsch machen, aber so:

Code: Alles auswählen

self.house = int(self.house)
jo das wäre noch ne möglichkeit, aber ich bin mir fast sicher, dass es in python noch eleganter geht ;)

Verfasst: Montag 1. Dezember 2008, 17:56
von Leonidas
Du weißt schon dass die ``__`` nicht "private" bedeuten, oder?

Verfasst: Montag 1. Dezember 2008, 18:09
von ede
Leonidas hat geschrieben:Du weißt schon dass die ``__`` nicht "private" bedeuten, oder?
ich wollte halt deutlich machen, dass es sich dabei um member handelt. außerdem soll folgendes nicht möglich sein:

Code: Alles auswählen

addr.__street = "Finkenweg"

Verfasst: Montag 1. Dezember 2008, 18:11
von Leonidas
ede hat geschrieben:
Leonidas hat geschrieben:Du weißt schon dass die ``__`` nicht "private" bedeuten, oder?
ich wollte halt deutlich machen, dass es sich dabei um member handelt.
Es sind so oder so Member, das machst du ja schon durch zu Zuweisung zu einem Attribut von ``self`` deutlich. Das ``__`` macht es nur schwerer lesbar.

Verfasst: Montag 1. Dezember 2008, 18:16
von bwbg
Da drängt sich die Frage auf, wieso eine Attributzuweisung nicht erfolgen darf.

Im Grund benötigt man die Hausnummer als Zahl nicht, es sei denn, man muss damit rechnen. Es wäre am einfachsten, die komplette Anschrift als eine Zeichenkette zu verwenden. So deckst du auch Fälle ab, in der eine Anschrift einen Nummernbereich umfasst oder Buchstaben enthält:

Finkenstraße 15-21
Sachsenring 44b

Wäre es nicht besser, die Datenherkunft (hier der Datensatz) von der Klasse zu trennen und statt dessen eine Funktion zu verwenden, welche Adressobjekte zurückliefert.

Grüße... Heiko

Verfasst: Montag 1. Dezember 2008, 18:26
von ede
Leonidas hat geschrieben:
ede hat geschrieben:
Leonidas hat geschrieben:Du weißt schon dass die ``__`` nicht "private" bedeuten, oder?
ich wollte halt deutlich machen, dass es sich dabei um member handelt.
Es sind so oder so Member, das machst du ja schon durch zu Zuweisung zu einem Attribut von ``self`` deutlich. Das ``__`` macht es nur schwerer lesbar.
is ja auch nich so wichtig: es soll die member nur vor einem zugriff von außen schützen, da hilft der doppelte unterstrich aber leider auch nix :?
weißt du wie man die direkte zuweisung an member unterbinden kann?

aber zurück zum problem, es müssen wirklich integerwerte sein! ich will, wie gesagt, die datensätze vergleichen und sortieren können.

Verfasst: Montag 1. Dezember 2008, 18:44
von yipyip
Suchst du etwa sowas?

Code: Alles auswählen

In [37]: a, b, c = (f(y) for f, y in zip([str]*2 + [int], 'maier|lerchenweg|15'.split('|')))

In [38]: a
Out[38]: 'maier'

In [39]: b
Out[39]: 'lerchenweg'

In [40]: c
Out[40]: 15
:wink:
yipyip

Verfasst: Montag 1. Dezember 2008, 18:45
von BlackVivi
ede hat geschrieben:aber zurück zum problem, es müssen wirklich integerwerte sein! ich will, wie gesagt, die datensätze vergleichen und sortieren können.
Darum würde ich mir aber erst Sorgen machen, wenn ich sortiere und vergleiche... Das geht beides auch gut mit Strings. Falls du Angst hast, das es nich richtig sortiert wird... speicherst du eben die Hausnummern mit führenden nullen... dann wird es auch richtig sortiert. Es ist einfach keine gute Idee, Integer für Sachen zu nehmen, die nicht für Integer gedacht sind.

Aber nun gut... wenn du es machen _möchtest_ ...

Code: Alles auswählen

>>> dataset = "maier|lerchenweg|15"
>>> args = []
>>> for i in dataset.split("|"):
...     try:
...         args.append(int(i))
...     except:
...         args.append(i)
...
>>> args
['maier', 'lerchenweg', 15]
>>> type(args[2])
<type 'int'>
Damit wird alles in eine Zahl gewandelt, was auch in'ne Zahl gewandelt werden kann.

Verfasst: Montag 1. Dezember 2008, 18:48
von Birne94

Code: Alles auswählen

>>> dataset = "maier|lerchenweg|15"
>>> args = []
>>> for i in dataset.split("|"):
...     try:
...         args.append(int(i))
...     except ValueError:
...         args.append(i)
...
>>> args
['maier', 'lerchenweg', 15]
>>> type(args[2])
<type 'int'>
Ich würde die Exception genauer definieren ;-)
Das erleichert imo später das Verstehen deines Codes ein wenig^^

Verfasst: Montag 1. Dezember 2008, 18:49
von BlackVivi
Birne94 hat geschrieben:Ich würde die Exception genauer definieren ;-)
Arg, jop. Zu schnell geschrieben... Danke.

Verfasst: Montag 1. Dezember 2008, 19:41
von numerix
ede hat geschrieben:weißt du wie man die direkte zuweisung an member unterbinden kann?
In der Regel genügt es, wenn du ein Attribut durch EINEN vorangestellten Unterstrich kennzeichnest. Per Konvention bedeutet das soviel wie "Finger weg".

Wer trotzdem eine Zuweisung vornimmt und am Ende mit Problemen dasteht, ist dann selbst schuld.

Sieh dir doch mal property() an. Vielleicht gefällt dir das.

Verfasst: Montag 1. Dezember 2008, 23:41
von Leonidas
ede hat geschrieben:es soll die member nur vor einem zugriff von außen schützen, da hilft der doppelte unterstrich aber leider auch nix :?
weißt du wie man die direkte zuweisung an member unterbinden kann?
Mit read-only Properies, aber wozu brauchst du das?

Verfasst: Montag 1. Dezember 2008, 23:46
von BlackVivi
Leonidas hat geschrieben:
ede hat geschrieben:es soll die member nur vor einem zugriff von außen schützen, da hilft der doppelte unterstrich aber leider auch nix :?
weißt du wie man die direkte zuweisung an member unterbinden kann?
Mit read-only Properies, aber wozu brauchst du das?
Geheimnisprinzip ^__^

Find das Geheimnisprinzip aber nicht so sinnvoll ._. Wenn das Attribut nicht geändert werden muss, wirds doch eh nich geändert. Und wenns das muss, wirds. Wozu es verstecken oder verbieten es zu ändern...?

Aber vielleicht bin ich auch einfach zu doof um es richtig zu verstehen.

Verfasst: Mittwoch 3. Dezember 2008, 14:43
von sma

Code: Alles auswählen

[f(d) for f, d in zip((str, int, float, bool), "abc,2,5.5,True".split(","))]
Stefan

Verfasst: Mittwoch 3. Dezember 2008, 15:24
von BlackVivi
Ist bool bei True wirklich die richtige Wahl?.. Es kommt bei True zwar das richtige heraus... Aber nur weil der String nich leer is.

Code: Alles auswählen

>>> bool("False")
True
Vielleicht wäre

Code: Alles auswählen

lambda x: x == "True"
besser...

Verfasst: Mittwoch 3. Dezember 2008, 15:34
von sma
Stümmt, ganz so einfach geht das leider nicht. Man kann `eval` in diesem Fall benutzen. Oder sogar immer, müsste dann aber Strings nochmal explizit in Anführungszeichen einschließen :)

Stefan