2011-11-07 71 views
5

Tôi đã viết một chương trình bằng Tkinter (Python 2.7), một scrabblehelper bằng tiếng Na Uy có chứa một số ký tự đặc biệt (æøå), có nghĩa là danh sách từ của tôi (ordliste) chứa các từ có ký tự đặc biệt.UnicodeWarning: các ký tự đặc biệt trong Tkinter

Khi tôi chạy finnord chức năng của mình (c *), nó trả về 'cd'. Tôi đang sử dụng một số entry.get() để có được từ để đưa vào chức năng của tôi.

Vấn đề của tôi là mã hóa của entry.get(). Tôi có mã hóa địa phương UTF-8, nhưng tôi nhận được UniCodeError khi tôi viết bất kỳ ký tự đặc biệt nào trong hộp nhập của tôi và khớp chúng vào danh sách từ của tôi.

Đây là kết quả của tôi.

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 

Khi tôi viết trong vỏ của tôi:

> 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 

Bất cứ ai cũng biết tại sao tôi không thể kết hợp ordinn.get() (entry) để wordlist của tôi?

Trả lời

6

tôi có thể sao chép các lỗi theo cách này:

% 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 

Vì vậy, có lẽ là một sstr objectliste hoặc ordliste chứa unicode, hoặc (như eryksun chỉ ra trong các ý kiến) ngược lại. Giải pháp là giải mã str object s (rất có thể với codec utf-8) để làm cho chúng unicode.

Nếu điều đó không giúp đỡ, xin vui lòng in ra và gửi đầu ra của

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

Tôi tin rằng vấn đề có thể tránh được bằng cách chuyển đổi tất cả các chuỗi để unicode.

  1. Khi bạn tạo ordliste từ norsk.txt, sử dụng 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. Chuyển đổi tất cả người dùng nhập vào để Unicode càng sớm càng tốt:

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

Vì vậy, có lẽ thử điều này:

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

Hoặc từ danh sách là UTF-8 (' 'k \ xc3 \ xb8 ** e'') và s từ' Entry.get() 'là Unicode mà hasn' đã được mã hóa. Nó mang lại cùng một lỗi. – eryksun

+0

@eryksun: Vâng, cảm ơn. – unutbu

+0

repr (%), s, liste và ordliste tất cả trả về cùng một giá trị như ban đầu. [link] (http://pastebin.com/0MfJVLqf) ** bold ** đây là kịch bản của tôi. Tôi có thể ' – Martol1ni