[英]decode/encode problems
我目前在Linux(Ubuntu)下编码/编码时遇到严重问题。 我以前从来不需要处理它,所以我不知道为什么这实际上不起作用!
我正在从/ usr / share / applications /解析*.desktop
文件,并提取信息,该信息通过HTTPServer在Web浏览器中显示。 我正在使用jinja2
进行模板制作。
首先,我在jinja2.Template.render()
的调用中收到UnicodeDecodeError
,该jinja2.Template.render()
表示
utf-8 cannot decode character XXX at position YY [...]
因此,我将所有来自appfind
-module(解析*.desktop
文件)的值都appfind
仅返回unicode字符串。
到目前为止,此位置的问题已解决,但是在某个时候,我正在将函数返回的字符串写入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
不会解决问题吗?
谢谢,
尼克拉斯
这可能很明显,但是无论如何:wfile是一个普通的字节流:写入的所有内容在写入时都必须为unicode.encode():ed。
在阅读OP时,我不清楚正在做什么。 但是,有些技巧可能会对您有所帮助,我发现这些技巧有助于调试编码问题。 如果这是您早已超越的东西,我事先表示歉意。
文件上的cat -v
将所有非ASCII字符输出为'^ X',这是我发现决定文件真正编码方式的唯一可靠方法。 UTF-8非ASCII字符是多字节。 这意味着它们将是cat -v
一个以上'^'条目的序列。
根据我的经验,shell环境(LC_ALL等)是导致问题的最常见原因。 确保您的系统同时具有UTF-8和latin-1可用的语言环境。 始终将LC_ALL设置为明确命名编码的语言环境,例如LC_ALL=sv_SE.iso88591
。
在bash和zsh中,您可以运行具有特定环境更改的命令,如下所示:
$ LC_ALL=sv_SE.utf8 python ./foo.py
与不必导出不同的语言环境相比,这使测试变得容易得多,并且不会污染外壳。
不要以为您内部有unicode字符串。 编写断言语句以验证字符串是否为unicode。
assert isinstance(foo, unicode)
学会识别正在使用的编码中常见字符的错误拼写/歪曲版本。 例如,'\\ xe4'是latin-1的一个diaresis,而'Ã'是组成一个diaresis的两个UTF-8字节,在latin-1中被错误地表示。 我发现了解这种gorp可以大大减少调试编码问题。
您需要对字节字符串和Unicode字符串采取规范的方法。 这就解释了这一切: 实用Unicode,或如何停止疼痛?
默认情况下,当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字符串后,将其转换为jinja2所需的unicode形式。
如果这样做没有帮助,请您添加您看到的第二个错误,并附上代码片段以阐明正在发生的事情?
尝试在代码段中所有出现的情况下使用.encode(encoding)
而不是.decode(encoding)
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.