我的代码带有UnicodeEncodeError

时间:2014-07-12 10:38:12

标签: python unicode ascii non-ascii-characters

我的users_information列表中的UnicodeEncodeError存在问题:

{u'\u0633\u062a\u064a\u062f@nimbuzz.com': {'UserName': u'\u0633\u062a\u064a\u062f@nimbuzz.com', 'Code': 5, 'Notes': '', 'Active': 0, 'Date': '12/07/2014 14:16', 'Password': '560pL390T', 'Email': u'yuyb0y@gmail.com'}}

我需要运行此代码来获取用户信息:

def get_users_info(type, source, parameters):
    users_registertion_file = 'static/users_information.txt'
    fp = open(users_registertion_file, 'r')
    users_information = eval(fp.read())
    if parameters:
        jid = parameters+"@nimbuzz.com"
        if users_information.has_key(jid):
            reply(type, source, u"User name:\n" +str(users_information[jid]['UserName'])+ u"\nPassword:\n" +str(users_information[jid]['Password'])+ u"\nREG-code:\nP" +str(users_information[jid]['Code'])+ u"\nDate:\n" +str(users_information[jid]['Date'])+ u"\naccount status:\n " +str(users_information[jid]['Active']))
        else:
            reply(type, source, u"This user " +parameters+ u"  not in user list")
    else:
        reply(type, source, u"write the id after command")

但是当我尝试获取用户信息时,我收到此错误:

UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-3: ordinal not in range(128)

我尝试使用jid

unicode('utf8')进行解码
jid = parameters.encode('utf8')+"@nimbuzz.com"

但是我得到了同样的错误:

UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-3: ordinal not in range(128)

请问我如何解决这个问题,因为您看到users_information列表中的UserName键如下所示:

u'\u0633\u062a\u064a\u062f@nimbuzz.com'

和users_information列表位于txt文件中。

2 个答案:

答案 0 :(得分:0)

除非jid是unicode字符串,否则您将找不到您的用户信息。请确保此处parameters为unicode值,并且此处string formatting更易于使用:

jid = u"{}@nimbuzz.com".format(parameters)

如果您使用编码的字节字符串,Python将在字典中找到您的用户名,因为它不知道您使用的字符串编码并且不会隐式解码或编码进行比较。

接下来,如果不指定编解码器,则无法在Unicode值上调用str()

str(users_information[jid]['UserName'])

如果UnicodeEncodeError包含除ASCII代码点以外的任何内容,则可以保证抛出users_information[jid]['UserName']异常。

您需要始终使用 Unicode 值,将值编码保留到最后一刻(最好将其保留到库中)。

您也可以在此处使用带unicode个对象的字符串格式:

reply(type, source, 
      u"User name:\n{0[UserName]}\nPassword:\n{0[Password]}\n"
      u"REG-code:\nP{0[Code]}\nDate:\n{0[Date]}\n"
      u"account status:\n {0[Active]}".format(users_information[jid]))

这会插入来自users_information[jid]的各种密钥,而不会在每个值上调用str

请注意,dict.has_key()已被弃用;使用in运算符来测试密钥:

if jid in users_information:

最后但并非最不重要的是,如果可以避免,请不要使用eval()。你应该在这里使用JSON作为文件格式,但如果你不能影响它,那么至少在文件内容而不是eval()上使用ast.literal_eval()并限制的允许输入 Python文字语法:

import ast

# ...

users_information = ast.literal_eval(fp.read())

答案 1 :(得分:-1)

几年前我遇到了一些问题:

jid = parameters+"@nimbuzz.com"

必须是

jid = parameters+u"@nimbuzz.com"

并将其放在第一行或第二行:

#coding:utf8

Martijn Pieters的例子 - 在我的机器上

Python 2.7.8 (default, Jul  1 2014, 17:30:21) 
[GCC 4.9.0 20140604 (prerelease)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> a=u'asdf'
>>> b='ваывап'
>>> a+b
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xd0 in position 0: ordinal not in range(128)
>>> c=u'аыиьт'
>>> a+c
u'asdf\u0430\u044b\u0438\u044c\u0442'
>>>