Formattieren von Nicht-7-bit-Strings

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.
Benutzeravatar
kajarno
User
Beiträge: 26
Registriert: Samstag 16. Januar 2010, 12:41
Wohnort: München
Kontaktdaten:

Ich versuche Texte zu formattieren, die nicht 7-bit sind. Die Spalten sind aber schief, da für die Format-Länge irgendein Speicherbedarf benutzt wird, anstatt Druckbreite.

Programmcode (unter Mac OS X):

Code: Alles auswählen

#!/usr/bin/env python 
# -*- coding: utf-8 -*-

mitundohneumlaute = ["Gemüse","Obst","München", "1¾", "Herrlich", "Wunderbar"]

for item in mitundohneumlaute:
  print "%-9s %2s %6s" % (item, len(item), "Schief")
Die Spalten sind schief und "Gemüse" hat eine Länge von 7:

Code: Alles auswählen

Gemüse    7 Schief
Obst       4 Schief
München   8 Schief
1¾        3 Schief
Herrlich   8 Schief
Wunderbar  9 Schief
Kriege ich irgendwie gerade Spalten hin?
Kaj Arnö, Sun VP MySQL Community Relations
Vormals (1979-99) Programmierer, möchte 2010 alte Künste wiederbeleben, und zwar mit PyObjC und MySQLdb unter Mac. Aus Finnland, Muttersprache Schwedisch. Bevorzugt Deutsch über Englisch. In München seit 2006.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Code: Alles auswählen

>>> mitundohneumlaute = [u"Gemüse",u"Obst",u"München", u"1¾", u"Herrlich", u"Wunderbar"]
>>> for item in mitundohneumlaute:
...     print "%-9s %2s %6s" % (item, len(item), "Nicht schief")
...
Gemüse     6 Nicht schief
Obst       4 Nicht schief
München    7 Nicht schief
1¾         2 Nicht schief
Herrlich   8 Nicht schief
Wunderbar  9 Nicht schief
Das Leben ist wie ein Tennisball.
Benutzeravatar
kajarno
User
Beiträge: 26
Registriert: Samstag 16. Januar 2010, 12:41
Wohnort: München
Kontaktdaten:

u"Wünderbär"
u"Vielen herzlichen Dank!"
EyDu hat geschrieben:

Code: Alles auswählen

>>> mitundohneumlaute = [u"Gemüse",u"Obst",u"München", u"1¾", u"Herrlich", u"Wunderbar"]
>>> for item in mitundohneumlaute:
...     print "%-9s %2s %6s" % (item, len(item), "Nicht schief")
...
Gemüse     6 Nicht schief
Obst       4 Nicht schief
München    7 Nicht schief
1¾         2 Nicht schief
Herrlich   8 Nicht schief
Wunderbar  9 Nicht schief
Kaj Arnö, Sun VP MySQL Community Relations
Vormals (1979-99) Programmierer, möchte 2010 alte Künste wiederbeleben, und zwar mit PyObjC und MySQLdb unter Mac. Aus Finnland, Muttersprache Schwedisch. Bevorzugt Deutsch über Englisch. In München seit 2006.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

lesenswert: http://wiki.python-forum.de/Von%20Umlau ... 0Encodings (Wenn auch ReST immer noch nicht im Wiki geht...)

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Benutzeravatar
kajarno
User
Beiträge: 26
Registriert: Samstag 16. Januar 2010, 12:41
Wohnort: München
Kontaktdaten:

Ich habe mich etwas zu früh gefreut:

Code: Alles auswählen

#!/usr/bin/env python 
# -*- coding: utf-8 -*-
import codecs
mitundohneumlaute = [u"Gemüse",u"Obst",u"München",u"1¾",u"Herrlich", u"Wunderbar"]

for item in mitundohneumlaute:
  print "%-9s %2s %6s" % (item, len(item), "Schief")
ergibt

Code: Alles auswählen

kaj@Birger[kajtajm]$ umlautbeispiel.py 
Traceback (most recent call last):
  File "./umlautbeispiel.py", line 7, in <module>
    print "%-9s %2s %6s" % (item, len(item), "Schief")
UnicodeEncodeError: 'ascii' codec can't encode character u'\xfc' in position 3: ordinal not in range(128)
kajarno hat geschrieben:u"Wünderbär"
u"Vielen herzlichen Dank!"
EyDu hat geschrieben:

Code: Alles auswählen

>>> mitundohneumlaute = [u"Gemüse",u"Obst",u"München", u"1¾", u"Herrlich", u"Wunderbar"]
>>> for item in mitundohneumlaute:
...     print "%-9s %2s %6s" % (item, len(item), "Nicht schief")
...
Gemüse     6 Nicht schief
Obst       4 Nicht schief
München    7 Nicht schief
1¾         2 Nicht schief
Herrlich   8 Nicht schief
Wunderbar  9 Nicht schief
Kaj Arnö, Sun VP MySQL Community Relations
Vormals (1979-99) Programmierer, möchte 2010 alte Künste wiederbeleben, und zwar mit PyObjC und MySQLdb unter Mac. Aus Finnland, Muttersprache Schwedisch. Bevorzugt Deutsch über Englisch. In München seit 2006.
Benutzeravatar
kajarno
User
Beiträge: 26
Registriert: Samstag 16. Januar 2010, 12:41
Wohnort: München
Kontaktdaten:

Ja, lesenswert! Jetzt kriege ich die richtigen Längen aus len(), bekomme aber immer noch ein schiefes Output:

Code: Alles auswählen

#!/usr/bin/env python 
# -*- coding: utf-8 -*-
import codecs
import sys
mitundohneumlaute = [u"Gemüse",u"Obst",u"München",u"1¾",u"Herrlich", u"Wunderbar"]

for item in mitundohneumlaute:
  print u"%-9s %2s %6s".encode(sys.getfilesystemencoding()) % (item.encode(sys.getfilesystemencoding()), len(item), "Schief")

kaj@Birger[kajtajm]$ umlautbeispiel.py 
Gemüse    6 Schief
Obst       4 Schief
München   7 Schief
1¾        2 Schief
Herrlich   8 Schief
Wunderbar  9 Schief
jens hat geschrieben:lesenswert: http://wiki.python-forum.de/Von%20Umlau ... 0Encodings (Wenn auch ReST immer noch nicht im Wiki geht...)
Kaj Arnö, Sun VP MySQL Community Relations
Vormals (1979-99) Programmierer, möchte 2010 alte Künste wiederbeleben, und zwar mit PyObjC und MySQLdb unter Mac. Aus Finnland, Muttersprache Schwedisch. Bevorzugt Deutsch über Englisch. In München seit 2006.
fhoech
User
Beiträge: 143
Registriert: Montag 9. April 2007, 18:26

Code: Alles auswählen

import codecs
import sys
mitundohneumlaute = [u"Gemüse",u"Obst",u"München",u"1¾",u"Herrlich", u"Wunderbar"]

for item in mitundohneumlaute:
  print (u"%-9s %2s %6s" % (item, len(item), "Schief")).encode(sys.stdout.encoding or sys.getfilesystemencoding(), "replace")
Benutzeravatar
kajarno
User
Beiträge: 26
Registriert: Samstag 16. Januar 2010, 12:41
Wohnort: München
Kontaktdaten:

Nicht schief! Jetzt nicht zu früh gefreut - danke! :)

Code: Alles auswählen

kaj@Birger[kajtajm]$ umlautbeispiel.py 
Gemüse     6 Schief
Obst       4 Schief
München    7 Schief
1¾         2 Schief
Herrlich   8 Schief
Wunderbar  9 Schief
fhoech hat geschrieben:

Code: Alles auswählen

import codecs
import sys
mitundohneumlaute = [u"Gemüse",u"Obst",u"München",u"1¾",u"Herrlich", u"Wunderbar"]

for item in mitundohneumlaute:
  print (u"%-9s %2s %6s" % (item, len(item), "Schief")).encode(sys.stdout.encoding or sys.getfilesystemencoding(), "replace")
Kaj Arnö, Sun VP MySQL Community Relations
Vormals (1979-99) Programmierer, möchte 2010 alte Künste wiederbeleben, und zwar mit PyObjC und MySQLdb unter Mac. Aus Finnland, Muttersprache Schwedisch. Bevorzugt Deutsch über Englisch. In München seit 2006.
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

Du kannst das auch einfacher haben, indem du dein Terminal so einstellst, dass es Unicode darstellen kann(afaik ist das standardmäßig sowieso der Fall):

Dazu einfach im Terminal->Einstellungen->Einstellungen->Erweitert->Zeichen-Codierung->utf8
Benutzeravatar
kajarno
User
Beiträge: 26
Registriert: Samstag 16. Januar 2010, 12:41
Wohnort: München
Kontaktdaten:

Darii, danke für den Hinweis! Wusste ich nicht. Als ich nachgeschaut habe, hatte ich aber schon UTF8. Komisch. Die Python-Benutzeroberfläche weigert sich übrigens, Umlaute darzustellen. MySQL und der Shell nicht. Auch komisch.
Darii hat geschrieben:Du kannst das auch einfacher haben, indem du dein Terminal so einstellst, dass es Unicode darstellen kann(afaik ist das standardmäßig sowieso der Fall):

Dazu einfach im Terminal->Einstellungen->Einstellungen->Erweitert->Zeichen-Codierung->utf8
Kaj Arnö, Sun VP MySQL Community Relations
Vormals (1979-99) Programmierer, möchte 2010 alte Künste wiederbeleben, und zwar mit PyObjC und MySQLdb unter Mac. Aus Finnland, Muttersprache Schwedisch. Bevorzugt Deutsch über Englisch. In München seit 2006.
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

kajarno hat geschrieben:Die Python-Benutzeroberfläche weigert sich übrigens, Umlaute darzustellen.
Was ist die „Python-Benutzeroberfläche“? Was für eine Version benutzt du? Hast du irgendwas nachinstalliert? Das mitgelieferte Python hat jedenfalls keine derartigen Probleme.
Benutzeravatar
kajarno
User
Beiträge: 26
Registriert: Samstag 16. Januar 2010, 12:41
Wohnort: München
Kontaktdaten:

Darii hat geschrieben:
kajarno hat geschrieben:Die Python-Benutzeroberfläche weigert sich übrigens, Umlaute darzustellen.
Was ist die „Python-Benutzeroberfläche“? Was für eine Version benutzt du? Hast du irgendwas nachinstalliert? Das mitgelieferte Python hat jedenfalls keine derartigen Probleme.
Unter "Python-Benutzeroberfläche" verstehe ich dies:

Code: Alles auswählen

kaj@Birger[kajtajm]$ # Schaut mal: åäö. Na, in Deutschland eher ü als å.
kaj@Birger[kajtajm]$ python
Python 2.5.1 (r251:54863, Feb  6 2009, 19:02:12) 
[GCC 4.0.1 (Apple Inc. build 5465)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> print "Hier kriege ich keine Umalute, wenn ich noch so versuche"
Hier kriege ich keine Umalute, wenn ich noch so versuche
>>> 
Kaj Arnö, Sun VP MySQL Community Relations
Vormals (1979-99) Programmierer, möchte 2010 alte Künste wiederbeleben, und zwar mit PyObjC und MySQLdb unter Mac. Aus Finnland, Muttersprache Schwedisch. Bevorzugt Deutsch über Englisch. In München seit 2006.
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

Interessant, habs gerade mal mit der 2.6er ausprobiert die ich nie benutze geht wirklich nicht, installiert mal readline.

Code: Alles auswählen

sudo easy_install readline
Trotzdem erklärt das noch nicht den ASCII-encoding-Fehler den du da hattest.
fhoech
User
Beiträge: 143
Registriert: Montag 9. April 2007, 18:26

Achja, richtig. Unter Mac OS X liefert sys.stdout.encoding (afaik egal welche OS- und Pythonversion) "US-ASCII", obwohl das Terminal grundsätzlich mit UTF-8 läuft. Workaround: Falls das Python-Skript nur unter OS X lauffähig sein muss, statt sys.stdout.encoding einfach "UTF-8" verwenden.
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

fhoech hat geschrieben:Achja, richtig. Unter Mac OS X liefert sys.stdout.encoding (afaik egal welche OS- und Pythonversion) "US-ASCII", obwohl das Terminal grundsätzlich mit UTF-8 läuft.
Das ist mir neu und bei mir auch nicht der Fall.
Benutzeravatar
kajarno
User
Beiträge: 26
Registriert: Samstag 16. Januar 2010, 12:41
Wohnort: München
Kontaktdaten:

Darii, danke! Habe zuerst

Code: Alles auswählen

sudo easy_install -U setuptools
machen müssen (readline wollte eine neuere Version, >=0.6c9).

Dannach lief die easy_install von readline flott und jetzt sieht die Python-Commandzeile gut aus:

Code: Alles auswählen

kaj@Birger[kajtajm]$ python
Python 2.5.1 (r251:54863, Feb  6 2009, 19:02:12) 
[GCC 4.0.1 (Apple Inc. build 5465)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> print "såå jetzt bin ich äußerst zufrieden mit Umlauten an der Python-Befehlszeile"
såå jetzt bin ich äußerst zufrieden mit Umlauten an der Python-Befehlszeile
>>> 
Darii hat geschrieben:Interessant, habs gerade mal mit der 2.6er ausprobiert die ich nie benutze geht wirklich nicht, installiert mal readline.

Code: Alles auswählen

sudo easy_install readline
Trotzdem erklärt das noch nicht den ASCII-encoding-Fehler den du da hattest.
Kaj Arnö, Sun VP MySQL Community Relations
Vormals (1979-99) Programmierer, möchte 2010 alte Künste wiederbeleben, und zwar mit PyObjC und MySQLdb unter Mac. Aus Finnland, Muttersprache Schwedisch. Bevorzugt Deutsch über Englisch. In München seit 2006.
fhoech
User
Beiträge: 143
Registriert: Montag 9. April 2007, 18:26

Darii hat geschrieben:
fhoech hat geschrieben:Achja, richtig. Unter Mac OS X liefert sys.stdout.encoding (afaik egal welche OS- und Pythonversion) "US-ASCII", obwohl das Terminal grundsätzlich mit UTF-8 läuft.
Das ist mir neu und bei mir auch nicht der Fall.
Bei mir mit Python 2.5 und 2.6.4 unter OSX 10.4.11 defintiv so. Nur interessehalber: Welche Versionen verwendest du?
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

fhoech hat geschrieben:
Darii hat geschrieben:
fhoech hat geschrieben:Achja, richtig. Unter Mac OS X liefert sys.stdout.encoding (afaik egal welche OS- und Pythonversion) "US-ASCII", obwohl das Terminal grundsätzlich mit UTF-8 läuft.
Das ist mir neu und bei mir auch nicht der Fall.
Bei mir mit Python 2.5 und 2.6.4 unter OSX 10.4.11 defintiv so. Nur interessehalber: Welche Versionen verwendest du?
10.6 afair hatte ich damit unter 10.5 aber auch nie Probleme.
Benutzeravatar
kajarno
User
Beiträge: 26
Registriert: Samstag 16. Januar 2010, 12:41
Wohnort: München
Kontaktdaten:

Das Freuen betrifft allerdings nur noch Unicode-Texte aus der Programmdatei. Wenn ich die Daten aus der Datenbank lese, bekomme ich UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 3: ordinal not in range(128).

Code: Alles auswählen

#!/usr/bin/env python 
# -*- coding: utf-8 -*-
import codecs
import sys
import MySQLdb 

db = MySQLdb.connect(host='localhost', user='testuser', passwd='testpw',db="test")
c = db.cursor()
c.execute("select * from umlaute")
selectresult = c.fetchall()
for item in selectresult:
  umlautfld = item[0]
  print umlautfld, len(umlautfld);

for item in selectresult:
  umlautfld = item[0]
  print (u"%-9s %2s %6s" % (umlautfld, len(umlautfld), "Schief")).encode(sys.stdout.encoding or sys.getfilesystemencoding(), "replace")
ergibt

Code: Alles auswählen

kaj@Birger[kajtajm]$ umlautbeispiel.py 
Gemüse 7
Obst 4
München 8
1¾ 3
Herrlich 8
Wunderbar 9
Traceback (most recent call last):
  File "./umlautbeispiel.py", line 17, in <module>
    print (u"%-9s %2s %6s" % (umlautfld, len(umlautfld), "Schief")).encode(sys.stdout.encoding or sys.getfilesystemencoding(), "replace")
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 3: ordinal not in range(128)
Die Daten wurden ordnungsgemäß, erwünscht und recht problemlos als latin1 unter MySQL eingegeben:

Code: Alles auswählen

mysql> use test;
Database changed
mysql> create table umlaute (umlaute char(10));
Query OK, 0 rows affected (0.08 sec)
mysql> insert into umlaute values ("Gemüse"),("Obst"),("München"), ("1¾"), ("Herrlich"), ("Wunderbar"); 
Query OK, 6 rows affected (0.00 sec)
Records: 6  Duplicates: 0  Warnings: 0

mysql> select * from umlaute;
+-----------+
| umlaute   |
+-----------+
| Gemüse   |
| Obst      |
| München  |
| 1¾       |
| Herrlich  |
| Wunderbar |
+-----------+
6 rows in set (0.00 sec)

mysql> show create table umlaute;
+---------+---------------------------------------------------------------------------------------------------+
| Table   | Create Table                                                                                      |
+---------+---------------------------------------------------------------------------------------------------+
| umlaute | CREATE TABLE `umlaute` (
  `umlaute` char(10) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 |
+---------+---------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> select umlaute,length(umlaute) from umlaute;
+-----------+-----------------+
| umlaute   | length(umlaute) |
+-----------+-----------------+
| Gemüse   |               7 |
| Obst      |               4 |
| München  |               8 |
| 1¾       |               3 |
| Herrlich  |               8 |
| Wunderbar |               9 |
+-----------+-----------------+
6 rows in set (0.04 sec)

mysql> 
Dass MySQL die Längen von Zeichenketten mit Umlauten genauso falsch berechnet, liegt wohl daran, dass die Daten wie erwünscht in latin1 hinterlegt sind. Die latin1-Daten konnte ich ja auch unter Python lesen, aber nicht mehr in Unicode umwandeln. Ich habe mit sowohl encode als auch decode probiert, mit "utf-8" und mit "latin1" usw. aber der meckert, dass der "ascii decoder" die Umlaute nicht erkennt. Ich will ja auch sagen, dass es kein "ascii decoder" ist sondern "latin1", gelingt mir aber nicht.
kajarno hat geschrieben:Nicht schief! Jetzt nicht zu früh gefreut - danke! :)

Code: Alles auswählen

kaj@Birger[kajtajm]$ umlautbeispiel.py 
Gemüse     6 Schief
Obst       4 Schief
München    7 Schief
1¾         2 Schief
Herrlich   8 Schief
Wunderbar  9 Schief
Kaj Arnö, Sun VP MySQL Community Relations
Vormals (1979-99) Programmierer, möchte 2010 alte Künste wiederbeleben, und zwar mit PyObjC und MySQLdb unter Mac. Aus Finnland, Muttersprache Schwedisch. Bevorzugt Deutsch über Englisch. In München seit 2006.
Antworten