我目前在Linux(Ubuntu)下编码/编码存在严重问题。我之前从未需要处理过,所以我不知道为什么这实际上不起作用!
我正在从 / usr / share / applications / 解析*.desktop
个文件,并通过HTTPServer提取Web浏览器中显示的信息。我正在使用jinja2
进行模板化。
首先,我在致电UnicodeDecodeError
时收到jinja2.Template.render()
,其中说
utf-8 cannot decode character XXX at position YY [...]
所以我创建了来自appfind
- 模块(解析*.desktop
文件)的所有值,只返回unicode-strings。
到目前为止,这个地方的问题已经解决了,但是在某些时候我正在写一个函数返回到BaseHTTPServer.BaseHTTTPRequestHandler.wfile
插槽的字符串,我不能修复这个错误,无论编码是什么使用
此时,写入wfile
的字符串来自jinja2.Template.render()
,afaik返回一个unicode对象。
奇怪的是,它正在处理我的 Ubuntu 12.04 LTS ,而不是我朋友的 Ubuntu 11.04 LTS 。但是,这可能不是原因。他有更多的应用程序,也许他们会在*.desktop
文件中使用编码来引发错误。
但是,我在*.desktop
文件中正确检查了编码:
data = dict(parser.items('Desktop Entry'))
try:
encoding = data.get('encoding', 'utf-8')
result = {
'name': data['name'].decode(encoding),
'exec': DKENTRY_EXECREPL.sub('', data['exec']).decode(encoding),
'type': data['type'].decode(encoding),
'version': float(data.get('version', 1.0)),
'encoding': encoding,
'comment': data.get('comment', '').decode(encoding) or None,
'categories': _filter_bool(data.get('categories', '').
decode(encoding).split(';')),
'mimetypes': _filter_bool(data.get('mimetype', '').
decode(encoding).split(';')),
}
# ...
有人可以告诉我如何修复此错误吗?我已经读过关于SO的答案,我应该总是使用unicode()
,但实施起来会非常痛苦,而且我不认为在写入wfile
时会解决问题吗? / p>
谢谢,
尼古拉斯
答案 0 :(得分:3)
这可能很明显,但无论如何:wfile是一个普通的字节流:写入的所有内容必须是unicode.encode():ed。
阅读OP,我不清楚究竟是什么,正在进行中。但是,有一些技巧可以帮助你,我发现有助于调试编码问题。如果这是你早已超越的东西,我会提前道歉。
cat -v
会将所有非ascii字符输出为'^ X',这是我发现的唯一一种可以确定文件编码方式的简单方法。 UTF-8非ascii字符是多字节的。这意味着它们将是多个'^'的序列 - cat -v
的条目。
根据我的经验,Shell环境(LC_ALL等)是导致问题的最常见原因。确保您的系统具有包含UTF-8的语言环境,例如:拉丁-1可用。 始终将您的LC_ALL设置为明确命名编码的区域设置,例如LC_ALL=sv_SE.iso88591
。
在bash和zsh中,您可以运行具有该命令的特定环境更改的命令,如下所示:
$ LC_ALL=sv_SE.utf8 python ./foo.py
这使得测试比导出不同的语言环境容易得多,并且不会污染shell。
不要假设你内部有unicode字符串。编写断言语句,验证字符串是unicode。
assert isinstance(foo, unicode)
了解如何识别您正在使用的编码中的常见字符的错误/误传版本。例如。 '\ xe4'是latin-1 a diaresis而'ä'是两个UTF-8字节,构成一个diaresis,错误地用latin-1表示。我发现知道这种gorp可以大大减少调试编码问题。
答案 1 :(得分:1)
您需要对字节字符串和Unicode字符串采取严格的方法。这解释了一切:Pragmatic Unicode, or, How Do I Stop the Pain?
答案 2 :(得分:0)
默认情况下,当python遇到unicde的编码问题时,会抛出错误。但是,可以修改此行为,例如,如果错误是预期的或不重要的。
假设您正在两个作为ascii超集的unicode页面之间进行转换。两者都有相同的字符,但没有一对一的对应关系。因此,您可能希望忽略错误。
为此,请使用编码功能中的errors
变量。
mystring = u'This is a test'
print mystring.encode('utf-8', 'ignore')
print mystring.encode('utf-8', 'replace')
print mystring.encode('utf-8', 'xmlcharrefreplace')
print mystring.encode('utf-8', 'backslashreplace')
如果在读/写时使用了错误的编码,unicode会有很多问题。确保在获得unicode字符串后,将其转换为unicode desired by jinja2的形式。
如果这没有帮助,您能否添加您看到的第二个错误,可能还有一个代码段来澄清正在发生的事情?
答案 3 :(得分:0)
尝试在代码段中的所有匹配项中使用.encode(encoding)
代替.decode(encoding)
。