我在python中使用jinja2模板语言来显示一个网站。
相关的源代码如下:
# -*- coding: utf-8 -*-
...
template_values = {'name': u'abwärtz'}
template = jinja_environment.get_template('Home.html')
print( template.render(template_values) )
...
有趣的是,如果我使用:
template_values = {'name': u'abw_rtz'}
一切都很完美!
...对于Jinja2,假设模板的默认编码为 UTF-8。
...要明确使用Unicode字符串,必须在字符串前加上 文字与你:u'Hänsel和Gretel sagen Hallo'。那样的Python 将字符串存储为Unicode,方法是用字符串解码字符串 当前Python模块的字符编码。如果没有编码 指定此默认为'ASCII',这意味着您不能使用任何 非ASCII标识符....
所以,只需使用u'äöü',一切都应该有效,对吗?
这就是我得到的:
template_values = {'name': unicode('abwärtz','utf-8') }
UnicodeDecodeError: 'utf8' codec can't decode byte 0xe4 in position 3: invalid continuation byte
template_values = {'name': u'abwärtz' }
SyntaxError: (unicode error) 'utf8' codec can't decode byte 0xe4 in position 0: unexpected end of data
template_values = {'name': unicode('abwärtz',"ISO-8859-1") }
--> everything works just perfect!
我正在使用Windows 7,sys.getdefaultencoding()
返回ASCII。
有人可以解释这种奇怪的行为吗? 我正在寻找一个解决方案,其中'name':也处理中文或西里尔字符。
答案 0 :(得分:2)
问题很可能出在您用来保存此源文件的文本编辑器中。
源文件是编码字节。您的编辑必须决定如何存储ä
字符。在Windows上,许多文本编辑器将默认为您的OEM代码页,这通常是拉丁语1衍生物,称为代码页1252,而不是UTF-8。
如果你在文件的顶部添加一个编码声明,告诉Python字节是UTF-8,但那些字节不是真正的UTF-8,而是cp1252,Python会误解它们,导致{ {1}}如果你很幸运,如果你没有,那就很难跟踪mojibake。
如果您已经使用过西里尔字符或中文字符,问题可能会更加明显,因为尝试用cp1252(无法处理中文字符)保存带有中文字符的文件可能会给你一个几乎任何编辑器的警告或错误。但是将西欧字符保存为cp1252(可以处理它们)可能会默默地做错事。 (有一些编辑器 - 最值得注意的是emacs - 可以与Python共享他们的编码声明,所以如果你尝试用UnicodeDecodeError
保存文件,它将保存为UTF-8或者给你一个非常严厉的警告但是大多数编辑都不会知道你在编码声明中。“
你如何验证这是问题所在?
最简单的方法是在十六进制编辑器中查看您的源文件(或者只是以二进制模式打开它,如果您愿意,可以在Python脚本中对其进行hexlify)。如果这真的是UTF-8,你应该看到类似的东西:
# -*- coding: utf-8 -*-
如果它是cp1252,你会看到:
61 62 77 c3 a4 72 74 7a a b w . . r t z
区别在于两个61 62 77 e4 72 74 7a a b w ? r t z
字节('ä'为UTF-8)与c3 a4
(拉丁-1和cp1252,'ä')。
无论如何,您有两种解决方案:
e4
。答案 1 :(得分:0)
这个讨论很有启发性。谢谢大家的参与。
以下是我为解决自己案件所做的工作:
下载并安装免费的十六进制编辑器HxD。 (http://mh-nexus.de/en/downloads.php?product=HxD)
使用HxD打开相关的“文本”文件。
将Charset设置为DOS / IBM-ASCII。
目视查看奇数“字符”的“文字”。
将那些奇怪的“字符”替换为符合您要求的字符。搜索/替换下拉工具非常适用于此。
完成后保存文件。