python decoding/encoding hell (using jinja2)
我正在使用python中的jinja2模板语言来显示一个网站。
相关的源代码如下:
1 2 3 4 5 6 | # -*- coding: utf-8 -*- ... template_values = {'name': u'abw?rtz'} template = jinja_environment.get_template('Home.html') print( template.render(template_values) ) ... |
有趣的是如果我使用:
1 | template_values = {'name': u'abw_rtz'} |
一切正常!
根据Jinja2 S文件
...For Jinja2 the default encoding of templates is assumed to be
utf-8....To explicitly use a Unicode string you have to prefix the string
literal with a u: u'H?nsel und Gretel sagen Hallo'. That way Python
will store the string as Unicode by decoding the string with the
character encoding from the current Python module. If no encoding is
specified this defaults to ‘ASCII’ which means that you can’t use any
non ASCII identifier....
所以,只要用u'?"一切都会好起来的,对吧?
这就是我得到的:
1 2 | template_values = {'name': unicode('abw?rtz','utf-8') } UnicodeDecodeError: 'utf8' codec can't decode byte 0xe4 in position 3: invalid continuation byte |
1 2 | template_values = {'name': u'abw?rtz' } SyntaxError: (unicode error) 'utf8' codec can't decode byte 0xe4 in position 0: unexpected end of data |
1 2 | template_values = {'name': unicode('abw?rtz',"ISO-8859-1") } --> everything works just perfect! |
我正在研究Windows7和
有人能解释这种奇怪的行为吗?我正在寻找一个解决方案,其中"name":也处理中文或西里尔文字符。
问题很可能出现在用于保存此源文件的文本编辑器中。
源文件是经过编码的字节。您的编辑器必须决定如何存储该
如果在文件顶部添加一个编码声明,告诉python字节是utf-8,但这些字节不是真正的utf-8,而是cp1252,python会误解它们,导致
如果您已经使用了西里尔文或中文字符,那么问题可能会更明显,因为试图将一个包含中文字符的文件保存为CP1252(它无法处理中文字符),可能会对任何编辑器发出警告或错误。但是将西欧字符保存为CP1252(它可以处理这些字符)可能只是默默地做了错误的事情。(有一些编辑器,尤其是Emacs,可以与python共享它们的编码声明,因此,如果您尝试用该
您如何验证这是问题所在?
最简单的方法是在十六进制编辑器中查看源文件(或者在二进制模式下打开它,并在Python脚本中对其进行十六进制修改,如果您愿意的话)。如果这真的是UTF-8,您应该看到如下内容:
1 | 61 62 77 c3 a4 72 74 7a a b w . . r t z |
如果是CP1252,你会看到:
1 | 61 62 77 e4 72 74 7a a b w ? r t z |
区别是两个
无论如何,您有两种解决方案:
- 确保将编辑器配置为默认的UTF-8,并将现有的源文件从CP1252转换为UTF-8。
- 不要在源代码中使用任何非ASCII字符,而是编写
u'abw\u00e4rtz' 。
这个讨论很有启发性。感谢大家的参与。
以下是我为解决自己的案件所做的:
下载并安装hxd,一个免费的十六进制编辑器。(http://mh-nexus.de/en/downloads.php?产品= HXD)
使用hxd打开相关的"文本"文件。
将charset设置为dos/ibm-ascii。
目视检查"文本"中是否有奇怪的"字符"。
将那些奇怪的"字符"替换为符合您要求的字符。搜索/替换下拉工具非常适合这样做。
完成后保存文件。