2011-11-07 18 views
5

He escrito un programa en Tkinter (Python 2.7), un scrabblehelper en noruego que contiene algunos caracteres especiales (æøå), lo que significa que mi lista de palabras (ordliste) contiene palabras con caracteres especiales.UnicodeWarning: caracteres especiales en Tkinter

Cuando ejecuto mi función finnord (c *), devuelve 'cd'. Estoy usando un entry.get() para obtener la palabra para poner en mi función.

Mi problema es con la codificación de entry.get(). Tengo la codificación local UTF-8, pero obtengo un UniCodeError cuando escribo caracteres especiales en mi entrybox y los pongo en mi wordliste.

Aquí está mi salida.

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 

cuando escribo en mi concha:

> 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 

Cualquiera sabe por qué no puedo coincidir ordinn.get() (entrada) a mi lista de palabras?

Respuesta

6

puedo reproducir el error de esta manera:

% 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 

Así que tal vez es un sstr object, y liste o ordliste contiene unicode, o (como eryksun señala en los comentarios) viceversa. La solución es decodificar el str object s (muy probablemente con el códec utf-8) para hacerlos unicode.

Si eso no ayuda, por favor, imprimir y publicar la salida de

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

Creo que el problema se puede evitar mediante la conversión de todas las cadenas de unicode.

  1. Al generar ordliste de norsk.txt, utilice 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. convertir todas las entradas de usuario a unicode lo antes posible:

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

Así que tal vez intente esto:

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

o la palabra listas son UTF-8 (' 'k \ xc3 \ XB8 ** e'') y de s' Entry.get() 'es Unicode que hasn' t sido codificado Produce el mismo error. – eryksun

+0

@eryksun: Sí, gracias. – unutbu

+0

repr (%), s, liste y ordliste devuelven el mismo valor que su original. [link] (http://pastebin.com/0MfJVLqf) ** bold ** aquí está mi script. Puedo ' – Martol1ni