Seite 1 von 1

Unicode-Repräsentation von eigenen Klassen

Verfasst: Mittwoch 27. Mai 2009, 12:52
von fhoech
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)

Verfasst: Mittwoch 27. Mai 2009, 13:00
von Dauerbaustelle
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.

Verfasst: Mittwoch 27. Mai 2009, 16:32
von Trundle
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.

Verfasst: Mittwoch 27. Mai 2009, 16:50
von Dauerbaustelle
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

Verfasst: Mittwoch 27. Mai 2009, 18:04
von cofi
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.

Verfasst: Mittwoch 27. Mai 2009, 18:33
von 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.

Verfasst: Mittwoch 27. Mai 2009, 21:24
von Dauerbaustelle
Ich frage mich eigentlich, warum mit `errors='replace'` das Ganze nichtmehr funktioniert.

Verfasst: Mittwoch 27. Mai 2009, 22:02
von 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?

Verfasst: Mittwoch 27. Mai 2009, 23:00
von Dauerbaustelle
Auja, Denkfehler. Die __unicode__-Methode sollte ja schon ein Unicode-Objekt zurückgeben, da wird natürlich nichts mehr konvertiert...