Seite 1 von 2
Umlaute
Verfasst: Samstag 17. März 2012, 18:39
von MarcelF6
Hallo liebe Mitglieder,
weiss jemand, was man wie / wo ändern muss, damit python Statements à la:
versteht?
Das Problem liegt ja darin, dass nicht-ASCII-Zeichen per default nicht "erkannt" werden...
Danke im Voraus.
Re: Umlaute
Verfasst: Samstag 17. März 2012, 18:51
von cofi
Nein, das Problem liegt darin, dass "ß" ein _Bytestring_ ist. `string` also dasselbe Encoding haben muss wie deine Datei damit der Code funktioniert.
Code: Alles auswählen
In [4]: print re.sub('ß', 'ss', u'Straße')
Straße
In [5]: print re.sub(u'ß', 'ss', u'Straße')
Strasse
In [6]: print re.sub(u'ß', 'ss', 'Straße')
Straße
In [7]: print re.sub('ß', 'ss', 'Straße')
Strasse
Re: Umlaute
Verfasst: Samstag 17. März 2012, 19:22
von BlackJack
@MarcelF6: Du bekommst da doch ziemlich sicher eine Ausnahme. Wie lautet die denn? Komplett bitte. Hast Du den Text gelesen? Also auch dem Hinweis nachgegangen?
Re: Umlaute
Verfasst: Samstag 17. März 2012, 21:03
von MarcelF6
Ja, die Fehlermeldung besagt dass kein encoding definiert wurde. Also:
" [...]on line 17, but no encoding declared; see
http://www.python.org/peps/pep-0263.html for details "
Also es geht um folgenden Programmausschnitt:
Code: Alles auswählen
f = file(unicodeObjekt)
while True:
out = f.readlines()
out = out.lower()
ae = re.sub(u'ä', 'ae', out)
oe = re.sub(u"ö", "oe", ae)
ue = re.sub(u"ü", "ue", oe)
ss = re.sub(u"ß", "ss", ue)
return ss
f.close()
So "einfach" wie ich gedacht habe funktioniert das leider nicht. Also gibt es eine andere Möglichkeit das so zu machen wie ich es vor hatte?
Re: Umlaute
Verfasst: Samstag 17. März 2012, 21:06
von lunar
@MarcelF6: Lies für den Anfang doch einfach mal die Seite, auf welche in der Fehlermeldung verwiesen wird.
Re: Umlaute
Verfasst: Samstag 17. März 2012, 22:15
von BlackJack
@MarcelF6: `re.sub()` ist hier auch etwas mit Kanonen auf Spatzen geschossen. Wenn Du einfach nur statische Zeichenfolgen ersetzen willst, dann gibt es auf Zeichenketten dafür eine einfachere Methode.
Re: Umlaute
Verfasst: Samstag 17. März 2012, 22:27
von EyDu
Mich würde nun aber wirklich stark interessieren, aus welchem Grund du überall diese unnötigen ``while True`` verwendest.
Re: Umlaute
Verfasst: Samstag 17. März 2012, 22:30
von MarcelF6
Habe ich gemacht - so wie ich es verstanden habe muss man gewisse encodings vornehmen.
Ich habs mal probiert:
Code: Alles auswählen
#!/usr/bin/python
# -*- coding: utf-8 -*-#
import re
import sys
def funktion(unicodeObjekt):
'''Gib eine Datei auf der Standardausgabe aus.'''
f = unicode(file(unicodeObjekt))
f.unicode.encode('utf-8')
while True:
out = f.readlines()
out = out.lower()
ae = re.sub(u'ä', 'ae', out)
oe = re.sub(u"ö", "oe", ae)
ue = re.sub(u"ü", "ue", oe)
ss = re.sub(u"ß", "ss", ue)
return ss
f.close()
if len(sys.argv) < 2:
print 'Es wurden keine Parameter übergeben.'
sys.exit()
else:
for unicodeObjekt in sys.argv[1:]:
funktion(unicodeObjekt)
Wie gesagt: "probiert". Das Problem ist, dass ich aus der Beschreibung nicht ganz schlau wurde, was genau wie encodiert werden sollte..
@Blackjack: Ich habe als input einfach ein Unicode-Objekt.
@EyDu: Werd ich noch wegmachen

..hab das eben alles nacheinander geschrieben

Re: Umlaute
Verfasst: Samstag 17. März 2012, 22:47
von nomnom
- „while True“ ist sinnlos: Du verlässt die Schleife eh im ersten Durchgang.
- Du brauchst immer noch kein re.sub für einfache Substitutionen. „str.replace“ reicht vollkommen.
- „f.close()“ wird nie ausgeführt werden, da du vorher schon die Funktion verlässt.
- Wenn du kein Emacs verwendest kannst du auch „# coding: utf-8“ benutzen.
- Du probierst viel zu wild ‘rum!
Code: Alles auswählen
In [8]: unicode(file('blabla.txt'))
Out[8]: u"<open file 'blabla.txt', mode 'r' at 0x956e5a0>"
In [9]: _.unicode.encode('utf-8') # _ ist u"<open ...>"
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
/home/jakob/<ipython-input-9-3480aff0e5da> in <module>()
----> 1 _.unicode # _ ist u"<open ...>"
AttributeError: 'unicode' object has no attribute 'unicode'
Schau dir mal die Seiten aus Hyperions Signatur an, ich finde, dass Unicode und Encodings in Python da sehr gut erläutert werden:
Leonidas’ Folien —
Von Umlauten, Unicode und Encodings im Wiki —
Pragmatic Unicode – Präsentation von Ned Batchelder zu Unicode
Re: Umlaute
Verfasst: Samstag 17. März 2012, 22:48
von EyDu
Wie wäre es, wenn du uns auch das Beispiel gibst, mit dem du arbeitest? Ganz offensichtlich existiert die Funktion "normalize" nicht, wahrscheinlich ist "funktion" gemeint.
Folgender Code sieht auf jeden Fall falsch aus:
Code: Alles auswählen
f = unicode(file(unicodeObjekt))
f.unicode.encode('utf-8')
Zerlege das mal in einzelne Schritte und lasse dir die Zwischenergebnisse ausgeben. Den Trick solltest du jetzt ja eignetlich schon kennen.
Zum ``while-True``: Warum entfernst du es nicht bevor du es postest? Um so weniger Code wir lesen müssen, desto wahrscheinlicher ist es, dass dir geholfen wird. Vorallem wenn es um Abschnitte geht, auf die man die bereits hingeweisen hat.
Re: Umlaute
Verfasst: Sonntag 18. März 2012, 03:27
von MarcelF6
Danke für die Hilfe.
Also ich hab den Code auch nochmals überarbeitet:
Code: Alles auswählen
#!/usr/bin/python
# -*- coding: utf-8 -*-#
import sys
def funktion(unicodeObjekt):
'''Gib eine Datei auf der Standardausgabe aus.'''
with open(unicodeObjekt, "r") as f:
content = unicode(f.read())
return string.replace(content, 'ä', 'ae')
if len(sys.argv) < 2:
print 'Es wurden keine Parameter übergeben.'
sys.exit()
else:
funktion(sys.argv[1])
Allerdings hab ich immernoch eine Fehlermeldung:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 8: ordinal not in range(128)
Ich bin mir aber nicht sicher, ob das wirklich ein Problem wegen des Codes ist oder ob die Meldung vom Editor stammt. Denn jetzt reklamiert die shell auch bei normalen print-Statements mit ä,ö,ü dass sie keine ASCII-Characters seien. Woran genau liegt das Problem?
Dankeschön!
Re: Umlaute
Verfasst: Sonntag 18. März 2012, 08:55
von nomnom
Wenn du ein „unicode“-Objekt erstellen möchtest und kein Encoding angibst, dann wird angenommen, dass ASCII verwendet wurde.
Du musst wissen, in welchem Encoding deine Datei vorliegt und dann
aufrufen.
Code: Alles auswählen
return content.replace(u'ä', u'ae') # ist übrigens "besser" als string.replace, vor allem wenn man string gar nicht importiert
Re: Umlaute
Verfasst: Sonntag 18. März 2012, 09:05
von BlackJack
@nomnom: Du meinst sicher `decode()` nach dem einlesen…
@MarcelF6: Die Kodierungsprobleme beim ``print`` könnten daran liegen, dass Du versuchst `unicode`-Objekte auszugeben ohne sie vorher in `str` zu konvertieren. Und zwar mit der Kodierung die das Programm erwartet, dass die Zeichen dann darstellen soll.
Re: Umlaute
Verfasst: Sonntag 18. März 2012, 09:33
von nomnom
BlackJack hat geschrieben:@nomnom: Du meinst sicher `decode()` nach dem einlesen…
Ja, meinte ich …

Re: Umlaute
Verfasst: Sonntag 18. März 2012, 11:24
von MarcelF6
Danke euch beiden für die Hilfe.
@nomnom: Hast du es so gemeint? :
Code: Alles auswählen
def funktion(unicodeObjekt):
'''Gib eine Datei auf der Standardausgabe aus.'''
with open(unicodeObjekt, "r") as f:
content = unicode(f.read().decode('utf-8'))
return content.replace(u'ä', u'ae')
Re: Umlaute
Verfasst: Sonntag 18. März 2012, 11:53
von BlackJack
@MarcelF6: Erkläre mal was in der Zeile in der `content` an einen Wert gebunden wird in jedem einzelnen Schritt passiert. Welchen Typ haben zum Beispiel die jeweiligen Zwischenergebnisse und was machen die einzelnen Aufrufe? Da sollte Dir dann etwas auffallen.
Des weiteren ist der Funktionsname, der Name des Arguments, und der Docstring falsch, weil keines davon tatsächlich die Bedeutung korrekt wiedergibt. Also `funktion()` streng genommen schon, aber das ist an der Stelle doch ein wenig *zu* generisch um nützlich zu sein.
Re: Umlaute
Verfasst: Sonntag 18. März 2012, 12:24
von MarcelF6
Jetzt habe ich es so:
Code: Alles auswählen
deffunktion(unicodeObjekt):
'''Gib eine Datei auf der Standardausgabe aus.'''
with open(unicodeObjekt, "r") as f:
content = (f.read().decode('utf-8'))
print content.replace(u'ä', u'ae')
(Um die Namen kümmere ich mich dann nachher

)
Also, bei der ersten Erwähnung von content wird der Dateiinhalt gelesen und nach UTF-8 dekodiert. [zum Testen habe ich in der Datei einige ä,ö,ü]
Das müsste eigentlich iO sein, denn mit print-Statements erhalte ich auch den korrekt-dargestellten Dateiinhalt.
Dann aber reklamiert meine shell schon wieder:
Das merkwürdige ist: Auch wenn ich Kommentare mit ä,ö,ü mache, kommt nun diese Fehlermeldung. Wieso? Ich habe doch das UTF-8-Format - da sollte dies kein Problem sein...
Re: Umlaute
Verfasst: Sonntag 18. März 2012, 12:31
von BlackJack
@MarcelF6: Es wird nicht *nach* UTF-8 dekodiert, sondern *von*.
Du hast Bytewerte ausserhalb von ASCII in Deiner Quelltextdatei, dann musst Du dem Compiler über den Kommentar mitteilen in welcher Kodierung die sind. Das hat nichts damit zu tun ob von dem Code in dem Skript Dateien geladen werden und in welcher Kodierung *die* vorliegen.
Re: Umlaute
Verfasst: Sonntag 18. März 2012, 13:16
von MarcelF6
Und das mache ich so, oder:
# -*- coding: utf-8 -*-#
Also Code gesamthaft:
Code: Alles auswählen
# -*- coding: utf-8 -*-#
import sys
def funktion(unicodeObjekt):
'''Gib eine Datei auf der Standardausgabe aus.'''
with open(unicodeObjekt, "r") as f:
content = (f.read().decode('utf-8'))
print content.replace(u'ä', u'ae')
if len(sys.argv) < 2:
print 'Es wurden keine Parameter uebergeben.'
sys.exit()
else:
funktion(sys.argv[1])
Also eigentlich kann ich die Antwort so schon geben: Nein, so klappt es nicht. Obwohl ich gelesen habe, dass es so klappen müsste.
Re: Umlaute
Verfasst: Sonntag 18. März 2012, 13:41
von BlackJack
@MarcelF6: Da ist jetzt wieder die Frage was „klappt nicht” konkret bedeutet. Die Ausnahme das der Quelltext Zeichen ausserhalb ASCII enthält ohne das eine Kodierung angegeben ist, sollte zumindest nicht mehr kommen.
Was jetzt noch passieren kann, was ich aber auch schon erwähnt habe, ist das nicht erraten werden kann was der Prozess am anderen Ende der Standardausgabe für eine Kodierung erwartet. Dann wird dafür ASCII angenommen und das geht natürlich nicht wenn in dem `unicode`-Objekt, welches ausgegeben werden soll, etwas ausserhalb von ASCII enthalten sein sollte.