繁体   English   中英

解码/编码问题

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM