Seite 1 von 1

Object > String, Umlaute

Verfasst: Donnerstag 20. August 2009, 10:23
von da.dom
Hallo Zusammen,

habe (mal wieder) ein kleines Problem mit Umlauten.
Ich schreibe eine kleine Applikation die über COM auf Outlook und die gespeicherten Emails zugreift.

Bis zu der Stelle an der ich eine Liste von Emails habe bin ich bekommen, leider scheitert es mal wieder an einer Kleinigkeit:

Beim printen eines "Mail Object" wird der Betreff ausgegeben, leider scheint er dann aber nicht mit Umlauten umgehen zu können:

Code: Alles auswählen

print mailItems(i)

>>

Traceback (most recent call last):
  File "C:\Dokumente und Einstellungen\mtm\Desktop\OutlookExport.py", line 41, in <module>
    print mailItems(i).__str__()
  File "C:\Java\Python\lib\site-packages\win32com\client\dynamic.py", line 187, in __str__
    return str(self.__call__())
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf6' in position 2: ordinal not in range(128)
Frage:
Wie wandle ich ein Objekt in einen String um, der Umlaute zulässt?

Danke schon mal Dom

Verfasst: Donnerstag 20. August 2009, 10:27
von Dav1d

Code: Alles auswählen

string = string.encode('utf-8')
, das hat bei mir zumindest geholfen

Re: Object > String, Umlaute

Verfasst: Donnerstag 20. August 2009, 10:34
von Hyperion
da.dom hat geschrieben: Frage:
Wie wandle ich ein Objekt in einen String um, der Umlaute zulässt?
Du solltest Dir mal den Leitfaden im wiki ansehen:

[wiki]Von Umlauten, Unicode und Encodings[/wiki]

Mir haben damals zusätzlich die Folien von Leonidas zu diesem Thema aus einem Vortrag bei Münchner Python-Stammtisch geholfen:
[wiki]User Group München[/wiki]?action=AttachFile&do=view&target=unicode-folien.pdf

Zusätzlich nutze die SuFu hier im Board, da gabs haufenweise Threads zu diesem Thema, wo wirklich alles beleuchtet wurde :-)

Generell nur eines vorweg:
Python unterscheidet eben zwischen Strings, die in einem bestimmten Encoding im Speicher stehen und solchen, die als Unicode im Speicher stehen.
"utf-8 != unicode!" - war für mich damals die Erkenntnis schlecht hin.

Du solltest Dir auf jeden Fall per type() mal den Typen von einem MailItem ausgeben lassen. Dann siehst Du, ob Du ggf. ein Unicode-Objekt hast, das Du zur Ausgabe entsprechend encodieren kannst, oder ob es sich um einen bereits encodierten String handelt.

Edit: Und vergiss den "Tipp" von Dav1d! Schon alleine string als Namen zu verwenden ist mindestens mal unglücklich.

Verfasst: Donnerstag 20. August 2009, 10:42
von Dav1d
string als namen war sysmbolisch -.-

Re: Object > String, Umlaute

Verfasst: Donnerstag 20. August 2009, 11:15
von da.dom
Hyperion hat geschrieben:ll per type() mal den Typen von einem MailItem ausgeben lassen. Dann siehst Du, ob Du ggf. ein Unicode-Objekt hast, das Du zur Ausgabe entsprechend encodieren kannst, oder ob es sich um einen bereits encodierten String handelt.
Mir ist der Hintergrund, warum das ganze auf die Nase geht durchaus bewusst, das Problem das ich an der Stelle habe ist, das es sich bei mir nicht um einen String handelt sondern ein komplexes Object das nicht besonders gesprächig ist:

Code: Alles auswählen

<type 'instance'>
Mein Problem habe ich auf saubere Art gerade gelöst, durch Zufall (danke an MS für die gute Dokumentation ihrer COM Schnittstellen ^^) ein Attribut auf dem Mail Object gefunden dass mir das Subject als sauberen String ausgibt.

Das Problem interessiert mich dann aber trotzdem, aber vielleicht stehe ich ja auch dem Schlauch: Wenn ich ein Objekt in einen String umwandel, dann ruf er (nehme ich mal an) eine interne Methode auf (__str__?) die den String endweder default-mäßig baut oder durch ein vom Entwickler implementierte Ausgabe liefert. Dieser String (das ganze Objekt auch?) ist ja mit einem Encoding versehen. Intern scheint das Objekt (natürlich) Problemlos mit Umlaute umgehen zu können. Aber jetzt kommt Python, sagt dem Objekt das er ein String werden soll, intern wird die Methode aufgerufen, die ein String in einem bestimmten Encoding zurückliefert (?) Das der "print" Befehl da auf die Nase geht ok: er wird versuchen den String in unsere Consolen-Encoding um zu wandeln, aber warum geht auch das hier auf die Nase:

Code: Alles auswählen

    str(mailItems(i))
Ich hätte an der Stelle erwartet das er mir einen String zurücklichert in dem Encoding in dem die String-Methode des Objektes diesen eben definiert hat. Oder stehe ich gerade auf der Leitung :) ?

Verfasst: Donnerstag 20. August 2009, 12:07
von mkesper
Python < 3.0 verwendet ASCII als Standardcodierung für Strings, d.h. alles, was > 127 ist, erzeugt eine Fehlermeldung. Steht eventuell auch in den weiter oben verlinkten Hinweisen.

Verfasst: Donnerstag 20. August 2009, 12:11
von snafu
Soweit ich weiß, ruft `print` auch die __str__()-Methode des Objekts auf. Es ist im Ergebnis also das selbe wie eine vorherige Nutzung von str().

Code: Alles auswählen

In [1]: class Foo(object):
   ...:     def __str__(self):
   ...:         return "__str__() was called"
   ...:     
   ...:     

In [2]: foo = Foo()

In [3]: print foo
------> print(foo)
__str__() was called

In [4]: str(foo)
Out[4]: '__str__() was called'