Komisches Problem mit String.join(List) und __repr__

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.
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

Komisches Problem mit String.join(List) und __repr__

Beitragvon droptix » Samstag 3. März 2007, 02:21

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?
Benutzeravatar
nkoehring
User
Beiträge: 543
Registriert: Mittwoch 7. Februar 2007, 17:37
Wohnort: naehe Halle/Saale
Kontaktdaten:

Beitragvon nkoehring » Samstag 3. März 2007, 06:34

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 ^^
BlackJack

Beitragvon BlackJack » Samstag 3. März 2007, 10:07

@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__()``.
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

Beitragvon droptix » Samstag 3. März 2007, 19:26

Danke. Funzt bestens mit `repr(obj)` und hab den Bug dank `type(value)` auch gleich gefunden.
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Beitragvon sape » Sonntag 4. März 2007, 16:39

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 _
BlackJack

Beitragvon BlackJack » Sonntag 4. März 2007, 17:01

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):``.
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Beitragvon sape » Sonntag 4. März 2007, 17:23

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

Wer ist online?

Mitglieder in diesem Forum: beerus, Bing [Bot]