Unicode-Repräsentation von eigenen Klassen

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
fhoech
User
Beiträge: 143
Registriert: Montag 9. April 2007, 18:26

Ich habe gerade folgendes Problem und stehe auf dem Schlauch. Ich habe eine Klasse bzw. eine Instanz davon, mit diversen Attributen. Nun möchte ich für diese Klasse festlegen, dass eine Unicode-Repräsentation einer Instanz immer ein bestimmtes Attribut zurückgibt (das entweder als Unicode-String vorliegt, oder bei Parse-Fehler als einfacher Buffer). Soweit so gut:

Code: Alles auswählen

class MyClass:
    def __init__(self):
         self.myattr = 'ABC'
    def __str__(self):
            return self.myattr

myinstance = MyClass()
>>> unicode(myinstance)
>>> u'ABC'
Aber warum funktioniert folgendes nicht?

Code: Alles auswählen

>>> unicode(myinstance, errors='replace')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: coercing to Unicode: need string or buffer, instance found
(Windows XP, 32-Bit, Python 2.6)
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

Nimm doch folgendes:

Code: Alles auswählen

class Foo(object):
    def __unicode__(self):
        return u'abc'
Dann ists schon unicode :-)

Edit: Oh, ich sehe grade, du willst ein Attribut zurückgeben, dann bringt dir das hier vermutlich wenig.
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

Man kann `unicode()` nur Strings (bzw. eben `buffer`-Objekte) übergeben, wenn man das "encoding"- und/oder "error"-Argument übergibt. Steht so auch in der Dokumentation. Folglich müsstest du eben ``unicode(str(myinstance), errors='replace')`` machen.
"Der Dumme erwartet viel. Der Denkende sagt wenig." ("Herr Keuner" -- Bertolt Brecht)
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

Isnet.

Code: Alles auswählen

class Foo(object):
 def __unicode__(self):
  return str('Hallo')

>>> unicode(Foo())
'Hallo'
>>> unicode(Foo(), errors='replace')
Traceback (most recent call last):
  Line 6, in <module>
    unicode(Foo(), errors='replace')
TypeError: coercing to Unicode: need string or buffer, Foo found
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Is das eine Antwort auf Trundles Post?
Wenn ja: Er erklärt warum das _nicht_ geht. Was du da `unicode` übergibst ist eben der Typ `Foo` und kein String/Buffer. Daran ändert auch nichts, dass du die Rückgabe von `__unicode__` anpasst, denn das wird hier wohl nicht implizit aufgerufen.

Wie siehts denn damit aus die Kodierung in der Instanz, d.h. bei Aufruf einer Methode zu lösen? `myinstance.to_unicode()` ? Dass man `unicode` auf eine Klasse anwenden kann impliziert für mich eigtl, dass es String artig ist, aber dass muss es bei deinem Beispiel nicht sein, insofern wär das ein unerwartetes Verhalten.
BlackJack

@cofi: Das man `unicode()` auf einem Objekt aufrufen kann impliziert nicht, dass es "String-artig" ist. Die Methode wird zum Beispiel auch aufgerufen, wenn man ``u'%s' % obj`` ausführt.
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

Ich frage mich eigentlich, warum mit `errors='replace'` das Ganze nichtmehr funktioniert.
BlackJack

Wie sollte das denn funktionieren? Die `__unicode__()`-Methode nimmt halt keine Argumente (ausser `self`) entgegen? Und was sollte so ein Aufruf überhaupt bedeuten!?

Mal anders gefragt, wunderst Du Dich auch, dass ``int(obj, 16)`` nicht funktionieren wird, selbst wenn `obj.__int__()` implementiert ist?
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

Auja, Denkfehler. Die __unicode__-Methode sollte ja schon ein Unicode-Objekt zurückgeben, da wird natürlich nichts mehr konvertiert...
Antworten