Seite 1 von 1

Komisches Problem mit String.join(List) und __repr__

Verfasst: Samstag 3. März 2007, 02:21
von droptix
Wenn ich mit

Code: Alles auswählen

print "spam"
einen String ausgebe, erscheint dieser so: Nun habe ich hier eine Liste, die nach und nach mit Werten gefüllt wird. Die Werte sind eigentlich Strings:

Code: Alles auswählen

self._values_ = []
# self._values_.append(...)
Um dieses `_value_`-Attribut auch vernünftig ausgeben zu können, hab ich mir in der zugehörigen Klasse eine `__repr__`-Methode gebastelt:

Code: Alles auswählen

def __repr__(self):
    return "\n\t".join(self._values_)
Die erste Zeile soll also ganz vorn stehen und alle weiteren darunter mit einem Tabulator eingerückt. Ich erhalte aber folgende Fehlermeldung:

Code: Alles auswählen

Traceback (most recent call last):
  ...
  File "MyParser.py", line 37, in __repr__
    return "\n\t".join(self._values_)
TypeError: sequence item 1: expected string, instance found
Die Notlösung ist momentan diese hier:

Code: Alles auswählen

def __repr__(self):
    return "\n\t".join([value.__repr__() for value in self._values_])
Also rufe ich nochmal für jedes Item in der Liste `__repr__()` auf. Somit erhalte ich aber den String in Apostroph-Zeichen, was in meinem Fall irreführend sein kann:

Code: Alles auswählen

`spam`
Da der Python-Interpreter bei sowas selten lügt, ist mir vielleicht zwischendrin tatsächlich eine Instanz und kein String in die Liste gerutscht. Wie kriege ich den Typ der Variable raus?

Verfasst: Samstag 3. März 2007, 06:34
von nkoehring
testenshalber koenntest du doch einfach eine liste mit typen zurueckgeben...

also in etwa so:

Code: Alles auswählen

return [type(v) for v in self._values_]
und wenn das dir nicht weiterhilft, also du keine instanz in der liste findest... weiß ich auch nich was los ist ^^

Verfasst: Samstag 3. März 2007, 10:07
von BlackJack
@droptix: Die Methoden mit den doppelten Unterstrichen ruft man im Regelfall nicht selber auf. Ein ``repr(obj)`` sieht doch auch viel schöner aus als ``obj.__repr__()``.

Verfasst: Samstag 3. März 2007, 19:26
von droptix
Danke. Funzt bestens mit `repr(obj)` und hab den Bug dank `type(value)` auch gleich gefunden.

Verfasst: Sonntag 4. März 2007, 16:39
von sape
BlackJack hat geschrieben:@droptix: Die Methoden mit den doppelten Unterstrichen ruft man im Regelfall nicht selber auf.
Außerhalb einer klasse ja. Innerhalb kann man sich streiten:

Code: Alles auswählen

class Foo(object):
    def __init__(self):
        self._bar = [1,2,3,4,5,6,7,8,9]

    def __iter__(self):
        for _ in self._bar:
            yield _

    def eggs(self):
        # Finde ich nicht so schön.
        for _ in self:
            print _

        # Finde ich nachvollziehbarer.
        for _ in self.__iter__():
            print _

Verfasst: Sonntag 4. März 2007, 17:01
von BlackJack
Das ist megahässlich. :P

Mal davon abgesehen, das ich an ``for item in self:`` nichts unschönes erkennen kann, gibt es auch hier keinen Grund auf die "Unterstrich"-Methode zurückzugreifen: ``for item in iter(self):``.

Verfasst: Sonntag 4. März 2007, 17:23
von sape
BlackJack hat geschrieben:Das ist megahässlich. :P
Naja, OK :D Das mit dem ``iter(self)`` **sollte** ich mir durch den Kopf gehen lassen :P

lg