unicode Datein

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
hans_py
User
Beiträge: 13
Registriert: Sonntag 29. Januar 2012, 12:26

Hallo,

ich habe folgendes Problem, bei dem ihr mir vielleicht helfen könntet. Unter Python 2.* wurde
das infinity - Zeichen mit

Code: Alles auswählen

print u"\u221E" 


dargestellt. Unter Python 3.* können die einfachen Zeichen zwar eingebunden werden, also z.B.

Code: Alles auswählen

"\u0038 Stellen"
aber eben nicht das infinity - zeichen.

Hat jemand eine Lösung - Danke im Voraus ..
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Willkommen im Forum!

Ich weiss aber nicht worauf du raus willst:

Code: Alles auswählen

%> python3
Python 3.2.2+ (default, Jan  8 2012, 07:22:26) 
[GCC 4.6.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> "\u221E"
'∞'
>>> "\u0038 Stellen"
'8 Stellen'

Code: Alles auswählen

%> python2
Python 2.7.2+ (default, Jan 20 2012, 17:51:10) 
[GCC 4.6.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> print u"\u221E" 
∞
>>> print u"\u0038 Stellen"
8 Stellen
>>> 
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Man sollte sich aber nicht darauf verlassen, dass das so funktioniert. Unicode ist nur für interne Verarbeitung gedacht; für die Ausgabe sind (Byte-)Strings vorgesehen. Also in Python2 zum Beispiel:

Code: Alles auswählen

print u"\u221E".encode("utf-8")
hans_py
User
Beiträge: 13
Registriert: Sonntag 29. Januar 2012, 12:26

Vielen Dank für die schnellen Antworten,

tut mir leid, mein Beitrag war ungenau.
das Programm sollte in der Windows Welt erstellt werden. Dort liefert der

Code: Alles auswählen

"\u221E"
leider einen Fehler, bei Linux klappt es.

Fehlermeldung auf Console

.. return codecs.charmap_encode(input, self.errors, encoding_map)[0] ...
UnicodeEncodeError:'charmap' codec can't encode charkter '\u221e' in position 1:charakter maps to (undefinded)

Aus meiner Sicht hat Windows nur eine eingeschränkte Tabelle, da andere Zeichen dargestellt werden. Wie könnte das trotzdem klappen. Hat jemand eine Idee.
nomnom
User
Beiträge: 487
Registriert: Mittwoch 19. Mai 2010, 16:25

Ja, Windows hat keinen gescheiten Terminalemulator und deswegen kannst du viele Zeichen nicht auf der Konsole anzeigen.
hans_py
User
Beiträge: 13
Registriert: Sonntag 29. Januar 2012, 12:26

Auf Konsole wollte ich das nur testen. Gibt es denn eine Möglichkeit über einen
import (codecs) o.a. dieses Zeichen in einem Programm darzustellen?
Es geht einfach darum, eine Entfernungsmatrix in einem Label darzustellen und das Inf durch

Code: Alles auswählen

float("infinty")


ist dann doch eher eine Notlösung.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

nomnom hat geschrieben:Ja, Windows hat keinen gescheiten Terminalemulator und deswegen kannst du viele Zeichen nicht auf der Konsole anzeigen.
Bei einem `print` muss man aber ja auch ein `encoding` angeben, wie derdon es schon vorgeschlagen und demonstriert hat. Die Windows-CMD-Shell hat doch dieses `cp1252`-Encoding o.ä. Evtl. kann das dieses Zeichen ja doch abbilden?
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
nomnom
User
Beiträge: 487
Registriert: Mittwoch 19. Mai 2010, 16:25

Hyperion hat geschrieben:
nomnom hat geschrieben:Ja, Windows hat keinen gescheiten Terminalemulator und deswegen kannst du viele Zeichen nicht auf der Konsole anzeigen.
Bei einem `print` muss man aber ja auch ein `encoding` angeben, wie derdon es schon vorgeschlagen und demonstriert hat. Die Windows-CMD-Shell hat doch dieses `cp1252`-Encoding o.ä. Evtl. kann das dieses Zeichen ja doch abbilden?
Nein, geht nicht. Die haben das Zeichen einfach nicht. Das ist nur so ein »man nehme ASCII und füge 1 Bit hinzu«-Encoding. Hier ist ein Bild von allen Zeichen bei CP1252.
Zuletzt geändert von nomnom am Sonntag 29. Januar 2012, 17:53, insgesamt 1-mal geändert.
BlackJack

@hans_py: Du solltest vielleicht erst einmal klären *wo* Du das nun genau anzeigen willst. Jede Möglichkeit kann eine andere Kodierung erfordern; eventuell gar nicht gehen, falls das Zeichen in der erwarteten Kodierung nicht vorhanden ist; oder überhaupt keine Intervention erfordern, wenn man Unicode direkt übergeben kann. „Label” klingt so nach GUI und die meisten Python-Anbindungen für GUI-Toolkits kommen mit `unicode`-Objekten klar.
hans_py
User
Beiträge: 13
Registriert: Sonntag 29. Januar 2012, 12:26

Es sollte, wie gesagt in einer Matrix geprintet werden. Der Code ist nachstehend ausschnittsweise abgebildet,
müsste aber compilierbar sein. Statt dem float("infinity") wär halt ein echtes "infinity" besser.
Die Idee encoding mit ('latin1') zu verwenden, ist mir auch schon gekommen, konnte sie aber nicht
umsetzen.

Code: Alles auswählen

import tkinter as tk

class Graph(object): 

    def __init__(self):                                                            
       
        self.master = tk.Tk()              
        self.master.geometry("760x400+10+10")
                
        frame1 = tk.Frame(self.master)        
        frame1.place(x=0  , y=0, width=480, height=400)
        self.canv = tk.Canvas(frame1)
        self.canv.place(x=0, y=0, width=480, height=400)
        
        frame2 = tk.Frame(self.master, relief = "sunken", borderwidth = 1)
        frame2.place(x=470, y=0, width=290, height=400)
     
             
        self.dele  = [x*0 for x in range(100)]
        self.dele5 = [x*0 for x in range(10)]
        self.dele6 = [x*0 for x in range(10)]
        
        for i in range (0, 10):         
                   self.dele5     = tk.Label(self.master,text=str(i))
                   self.dele5.place(x=500+i*25, y=120, width=25, height=20)
                   self.dele6     = tk.Label(self.master,text=str(i)) 
                   self.dele6.place(x=481, y=140+i*20, width=25, height=20)
                   
        for i in range (0, 10):
               for j in range (0,10):
                   
                   self.dele [i*10+j]  = tk.Label(self.master,text="0", border=1)
                   self.dele [i*10+j]["bg"] = "#FFFF66"                   
                   self.dele [i*10+j].place(x=500+i*25, y=140+j*20, width=25, height=20)
                

        self.set_mwert (2,3, float("infinity"))   # genau hier ist da Problem

    def set_mwert (self,x,y,wert):
        count = y*10+x
        self.dele [count]["text"] = wert       
              
            
if __name__ == "__main__":   
    
    graph1 = Graph()               
    graph1.master.mainloop()
Andev
User
Beiträge: 24
Registriert: Dienstag 17. Januar 2012, 15:55

Natürlich unterstützt die Windows-Konsole Unicode, auch ohne jede CP-Umstellung. Das Problem ist hier vielmehr, dass viele Win32-Anwendungen nicht die gewünschten Daten/Formate zurückschicken. Empfehlen würde ich hier ohnehin Powershell, insbesondere Powershell ISE, das explizit die ganzen UNICODE-Probleme lösen soll.

Zumindest unter CPython muss das Problem dennoch umgangen werden, da die Einstellungen und Möglichkeiten der Konsole ignoriert werden. Bei mir hatte sich das Problem bisher noch nicht gestellt, daher wird vermutlich gleich jemand kommentieren können, weshalb das folgende keine gute Lösung oder wie das eleganter zu lösen ist. Screenshot

Dein Codebeispiel läuft bei mir übrigens mit ∞ ("\u221E") ohne jede Veränderung aus jeder Konsole heraus, aber möglicherweise habe ich Dein Problem verstanden.
BlackJack

@hans_py: Warum so ein kompliziertes Beispiel um das Problem zu zeigen? Ich kann kein Problem sehen:

Code: Alles auswählen

import Tkinter as tk


def main():
    root = tk.Tk()
    tk.Label(root, text=u'\u221E').pack()
    root.mainloop()


if __name__ == '__main__':
    main()
Da sollte ein Unendlich-Zeichen angezeigt werden.
hans_py
User
Beiträge: 13
Registriert: Sonntag 29. Januar 2012, 12:26

Alles klar, Problem erkannt. Vielen Dank für die Antworten. Das Problem war die Arbeit auf der
Windows Konsole. Also nochmal Danke. Tolles Forum ! :D
nomnom
User
Beiträge: 487
Registriert: Mittwoch 19. Mai 2010, 16:25

Andev hat geschrieben:Natürlich unterstützt die Windows-Konsole Unicode, auch ohne jede CP-Umstellung.
Ach wirklich? UTF-8 funktioniert bei mir weder bei Windows 7 noch bei Windows XP in der »cmd.exe«. Ohne irgendeine »CP-Umstellung«.
hans_py
User
Beiträge: 13
Registriert: Sonntag 29. Januar 2012, 12:26

Das Problem habe ich ebenso und auch keine Lösung. Aber außerhalb der Konsole ist Unicode machbar.
In meinem Beispiel gings nur um den Labeltext und in diese Richtung noch einmal Danke.

... Warum die Kodierung auf Konsole streikt ... :K
Andev
User
Beiträge: 24
Registriert: Dienstag 17. Januar 2012, 15:55

nomnom hat geschrieben:
Andev hat geschrieben:Natürlich unterstützt die Windows-Konsole Unicode, auch ohne jede CP-Umstellung.
Ach wirklich? UTF-8 funktioniert bei mir weder bei Windows 7 noch bei Windows XP in der »cmd.exe«. Ohne irgendeine »CP-Umstellung«.
Nicht?
Seit NT 3.0 ist Unicode (als UCS/UTF-16) in Windows implementiert. Deine Konsole sollte problemlos Unicodezeichen anzeigen, manipulieren und ausgeben können, solange die gewählt Schriftart die Zeichen unterstützt - bei Windows 7 mit "Lucida Console" der Fall. Manuell umstellen für Anwendungen wie Python auf UTF-8 kannst Du mit "chcp 65001". Das habe ich oben nur nicht als Lösung vorgeschlagen, da CPython damit Schwierigkeiten hat und in der Regel abstürzt (liegt m.E. an der gewählten CRT-Umsetzung). Daher auch die manuelle Umstellung innerhalb Pythons in meinem Beispiel oben auf UTF-16. Damit funktioniert das alles problemlos, zumindest unter Powershell (cmd ist unter Umständen noch weiter anzupassen, habe ich nicht weiter getestet).

Warum Du als Entwickler "cmd.exe" nutzt statt Powershell/Powershell ISE, insbesondere nach Deinen Kommentaren oben über den "Terminalemulator", ist mir ein Rätsel. Wenn Dir das immer noch nicht reicht, kannst Du mit Interix auch direkt eine Korn- oder Bash-Shell nutzen.
nomnom
User
Beiträge: 487
Registriert: Mittwoch 19. Mai 2010, 16:25

Andev hat geschrieben:
nomnom hat geschrieben:
Andev hat geschrieben:Natürlich unterstützt die Windows-Konsole Unicode, auch ohne jede CP-Umstellung.
Ach wirklich? UTF-8 funktioniert bei mir weder bei Windows 7 noch bei Windows XP in der »cmd.exe«. Ohne irgendeine »CP-Umstellung«.
Nicht?
Seit NT 3.0 ist Unicode (als UCS/UTF-16) in Windows implementiert. Deine Konsole sollte problemlos Unicodezeichen anzeigen, manipulieren und ausgeben können, solange die gewählt Schriftart die Zeichen unterstützt - bei Windows 7 mit "Lucida Console" der Fall. Manuell umstellen für Anwendungen wie Python auf UTF-8 kannst Du mit "chcp 65001". Das habe ich oben nur nicht als Lösung vorgeschlagen, da CPython damit Schwierigkeiten hat und in der Regel abstürzt (liegt m.E. an der gewählten CRT-Umsetzung). Daher auch die manuelle Umstellung innerhalb Pythons in meinem Beispiel oben auf UTF-16. Damit funktioniert das alles problemlos, zumindest unter Powershell (cmd ist unter Umständen noch weiter anzupassen, habe ich nicht weiter getestet).

Warum Du als Entwickler "cmd.exe" nutzt statt Powershell/Powershell ISE, insbesondere nach Deinen Kommentaren oben über den "Terminalemulator", ist mir ein Rätsel. Wenn Dir das immer noch nicht reicht, kannst Du mit Interix auch direkt eine Korn- oder Bash-Shell nutzen.
Inzwischen benutze ich „xfce4-terminal“ mit der „Bourne-again shell“. :) Allerdings stürzen meine Python-Programme, die Sonderzeichen ausgeben ab, wenn man versucht, sie unter Windows auszuführen. Ich habe bei der „cmd“ nicht kapiert, wo ich da Einstellungen treffen kann, deswegen blieb es auch bei der „Standard“-Schrift (die anscheinend kein Unicode unterstützt). Na ja. Ich ziehe mich mal aus der Diskussion zurück … Habe inzwischen ja auch nicht mehr die Möglichkeit mich damit zu beschäftigen. Möchte ich auch nicht …
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Natürlich unterstützt die Windows-Konsole Unicode, auch ohne jede CP-Umstellung.
Ach wirklich? UTF-8 funktioniert bei mir weder bei Windows 7 noch bei Windows XP in der »cmd.exe«. Ohne irgendeine »CP-Umstellung«.
@nomnom & Andev:
Das ist kein Widerspruch, da UTF-8 != UTF-16 != UTF-32. Die bilden zwar alle mehr oder weniger den Unicode-Zeichenraum ab, die Zeichen sind aber was UTF-8 angeht, sehr anders repräsentiert. Zusätzlich deckt UTF-32 einen größeren Zeichenraum ab, bzw. arbeitet UTF-16 mit Multi-Multibytetricks, um da aufzuschliessen. Windows nutzt seit langem UTF-16, mit UTF-8 hat Microsoft seine liebe Not, UTF-32 wird nicht unterstützt von OS-Seite. Für Python z.B. bedeutet dies, das Unicode-Strings auf Linux heutzutage meist in UTF-32 vorliegen, während auf Windows UTF-16 genutzt wird.

Während Unicode den theoretischen Zeichenraum spezifiziert, sind die UTFs die technische Realisierung davon.
lunar

@jerch: Dafür hat Linux seine liebe Not mit UTF-16 ;)
Andev
User
Beiträge: 24
Registriert: Dienstag 17. Januar 2012, 15:55

Die Unterschiede zwischen Unicode und UTF wurden bereits angesprochen, aber gut, dass das noch einmal deutlich gemacht wird.

Linux setzt auf UTF-8 und auch das erst seit wenigen Jahren, ich habe hier immer noch ein paar Altmaschinen rumsitzen ("Altmaschinen"! Aus 2001 bis 2003!), mit denen der Datenaustausch durch dieses unsägliche ASCII immer noch regelmäßig Kopfschmerzen verursacht. Dass die 4-Byte-Vorgabe in wchar_t eine UTF-32-Unterstützung eingeführt hat ist zwar richtig, aber keine eigentliche *NIX-Sache und unterscheidet sich nicht wesentlich von der Windowsunterstützung.
Unter Windows ist das wirkliche Problem die variable Bitlänge von UTF-16 (ursprünglich UCS-2 mit fester Länge), unzählige - auch gute - Programmierer haben damit ihre Schwierigkeiten und auch Python gehört zu den Programmen, in denen hier ein wenig unsauber gearbeitet wurde. Mit Python 3.3 wurde das ganze verschlimmbessert aber leider noch nicht gelöst. Hat wahrscheinlich auch keine hohe Priorität. Von den ganzen BOM-Ideologien möchte ich gar nicht erst anfangen.

Probleme mit UTF-8 unter Windows sollten aber schon lange der Vergangenheit angehören, reguläre Anwendungen hatten die ohnehin nie, und für Anwendungen mit Konsolenausgabe wurde vor ~8 Jahren die Konsole durch Powershell abgelöst wurde und die ISE-Variante für Entwickler soll explizit die Kompatibilitätsprobleme lösen.

Wäre natürlich trotzdem schön, wenn sich die Entwickler der verschiedenen Systeme endlich einmal zusammensetzen könnten um eine sinnvolle Lösung zur Interoperabilität zu finden, ähnlich den Browserherstellern bei HTML5. Diese ideologischen Grabenkämpfe sind eine furchtbare Sache ("UTF-16 is evil", "UTF-32 is stupid", "ASCII is enough for everybody", "Your shell cannot do what mine does").
Antworten