2011-11-07 16 views
5

Napisałem program w języku Tkinter (Python 2.7), scrabblehelper w języku norweskim, który zawiera pewne znaki specjalne (æøå), co oznacza, że ​​moja lista słów (ordliste) zawiera słowa ze znakami specjalnymi.UnicodeWarning: znaki specjalne w Tkinter

Po uruchomieniu funkcji finnord (c *) następuje powrót do "cd". Używam entry.get(), aby uzyskać słowo, aby wprowadzić moją funkcję.

Mój problem dotyczy kodowania obiektu entry.get(). Mam lokalne kodowanie UTF-8, ale dostaję UniCodeError, kiedy piszę jakieś specjalne znaki w moim polu wejściowym i dopasowując je do mojego wordliste.

Oto moje wyniki.

Warning (from warnings module): 
    File "C:\pythonprog\scrabble\feud.py", line 46 
if s not in liste and s in ordliste: 
UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode -  
interpreting them as being unequal 

gdy piszę w mojej skorupie:

> ordinn.get() 
u'k\xf8**e' 
> ordinn.get().encode('utf-8') 
'k\xc3\xb8**e' 
> print ordinn.get() 
kø**e 
> print ordinn.get().encode('utf-8') 
kø**e 

Każdy wie, dlaczego nie może się równać ordinn.get() (wejścia) do mojej liście słów?

Odpowiedz

6

mogę odtworzyć błąd w ten sposób:

% python 
Python 2.7.2+ (default, Oct 4 2011, 20:03:08) 
[GCC 4.6.1] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> 'k\xf8**e' in [u'k\xf8**e'] 
__main__:1: UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal 
False 

Więc może s jest str object i liste lub ordliste zawiera unicode, lub (jak wskazuje eryksun w komentarzach) odwrotnie. Rozwiązaniem jest dekodowanie str object s (najprawdopodobniej z kodem kodeka utf-8), aby były one unicode.

Gdyby tak nie pomaga, należy wydrukować i wysłać wyjścia

print(repr(s)) 
print(repr(liste)) 
print(repr(ordliste)) 

Wierzę, że problem można uniknąć poprzez przekształcenie wszystkie sznurki do unicode.

  1. Podczas generowania ordliste od norsk.txt, użyj codecs.open('norsk.txt','r','utf-8'):

    encoding = sys.stdin.encoding 
    with codecs.open('norsk.txt','r','utf-8') as fil: 
        ordliste = [line.rstrip(u'\n') for line in fil] 
    
  2. konwertować wszystkie wejścia użytkownikowi Unicode jak najszybciej:

    def get_unicode(widget): 
        streng = widget.get() 
        try: 
         streng = streng.decode('utf-8') 
        except UnicodeEncodeError: 
         pass 
        return streng 
    

Więc może spróbuj tego:

import Tkinter as tk 
import tkMessageBox 
import codecs 
import itertools 
import sys 

alfabetet = (u"abcdefghijklmnopqrstuvwxyz" 
      u"\N{LATIN SMALL LETTER AE}" 
      u"\N{LATIN SMALL LETTER O WITH STROKE}" 
      u"\N{LATIN SMALL LETTER A WITH RING ABOVE}") 

encoding = sys.stdin.encoding 
with codecs.open('norsk.txt','r',encoding) as fil: 
    ordliste = set(line.rstrip(u'\n') for line in fil) 

def get_unicode(widget): 
    streng = widget.get() 
    if isinstance(streng,str): 
     streng = streng.decode('latin-1') 
    return streng 

def siord(): 
    alfa=lagtabell() 
    try: 
     streng = get_unicode(ordinn) 
     ordene=finnord(streng,alfa) 
     if len(ordene) == 0: 
      # There are no words that match 
      tkMessageBox.showinfo('Dessverre..','Det er ingen ord som passer...') 
     else: 
      # Done: The words that fit the pattern 
      tkMessageBox.showinfo('Ferdig', 
       'Ordene som passer er:\n'+ordene.encode('utf-8')) 
    except Exception as err: 
     # There has been a mistake .. Check your word 
     print(repr(err)) 
     tkMessageBox.showerror('ERROR','Det har skjedd en feil.. Sjekk ordet ditt.') 

def finnord(streng,alfa): 
    liste = set() 
    for substitution in itertools.permutations(alfa,streng.count(u'*')): 
     s = streng 
     for ch in substitution: 
      s = s.replace(u'*',ch,1) 
     if s in ordliste: 
      liste.add(s) 
    liste = [streng]+list(liste) 
    return u','.join(liste)+u'.' 

def lagtabell(): 
    tinbox = get_unicode(bokstinn) 
    if not tinbox.isalpha(): 
     alfa = alfabetet 
    else: 
     alfa = tinbox.lower() 
    return alfa 

root = tk.Tk() 
root.title('FeudHjelper av Martin Skow Røed') 
root.geometry('400x250+450+200') 
# root.iconbitmap('data/ikon.ico') 

skrift1 = tk.Label(root, 
       text = '''\ 
Velkommen til FeudHjelper. Skriv inn de bokstavene du har, og erstatt ukjente med *. 
F. eks: sl**ge 
Det er kun lov til å bruke tre stjerner, altså tre ukjente bokstaver.''', 
       font = ('Verdana',8), wraplength=350) 
skrift1.pack(pady = 5) 

ordinn = tk.StringVar(None) 
tekstboks = tk.Entry(root, textvariable = ordinn) 
tekstboks.pack(pady = 5) 

# What letters do you have? Eg "ahneki". Leave blank here if you want all the words. 
skrift2 = tk.Label(root, text = '''Hvilke bokstaver har du? F. eks "ahneki". La det være blankt her hvis du vil ha alle ordene.''', 
       font = ('Verdana',8), wraplength=350) 
skrift2.pack(pady = 10) 

bokstinn = tk.StringVar(None) 
tekstboks2 = tk.Entry(root, textvariable = bokstinn) 
tekstboks2.pack() 

knapp = tk.Button(text = 'Finn ord!', command = siord) 
knapp.pack(pady = 10) 
root.mainloop() 
+1

lub wyraz wykazy są UTF-8 (' 'k \ xc3 \ xb8 ** e'') i s od' Entry.get() 'jest Unicode że hasn' t zostały zakodowane. Daje ten sam błąd. – eryksun

+0

@eryksun: Tak, dziękuję. – unutbu

+0

repr (%), s, liste i ordliste wszystkie zwracają tę samą wartość, co ich oryginał. [link] (http://pastebin.com/0MfJVLqf) ** bold ** tutaj jest mój skrypt. Mogę ' – Martol1ni