Python 在Jinja2模板中使用utf-8字符
我试图在使用Jinja2呈现模板时使用utf-8字符。以下是我的模板的外观:Python 在Jinja2模板中使用utf-8字符,python,python-2.7,utf-8,character-encoding,jinja2,Python,Python 2.7,Utf 8,Character Encoding,Jinja2,我试图在使用Jinja2呈现模板时使用utf-8字符。以下是我的模板的外观: <!DOCTYPE HTML> <html manifest="" lang="en-US"> <head> <meta charset="UTF-8"> <title>{{title}}</title> ... 现在的问题是,myvar是从消息队列读取的消息,可能包含那些特殊的utf8字符(例如“Séptimo Cine”) 渲
<!DOCTYPE HTML>
<html manifest="" lang="en-US">
<head>
<meta charset="UTF-8">
<title>{{title}}</title>
...
现在的问题是,myvar是从消息队列读取的消息,可能包含那些特殊的utf8字符(例如“Séptimo Cine”)
渲染的模板类似于:
...
<title>S\u00e9ptimo Cine</title>
...
。。。
S\u00e9ptimo电影
...
我希望它是:
...
<title>Séptimo Cine</title>
...
。。。
塞普蒂莫电影
...
我做了好几次测试,但都没能成功
- 我尝试在不使用.encode(“utf8”)的情况下设置title变量,但它引发了一个异常(ValueError:应为bytes对象,而不是unicode对象),因此我猜测初始消息是unicode
- 我使用了chardet.detect来获取消息的编码(它是“ascii”),然后执行了以下操作:myvar.decode(“ascii”).encode(“cp852”),但标题仍然没有正确呈现
- 我还确保我的模板是一个UTF-8文件,但这并没有什么区别
有什么想法吗?尝试将“渲染”命令更改为此
template.render(index_variables).encode( "utf-8" )
Jinja2的文档说“这将以unicode字符串的形式返回呈现的模板。”
希望这有帮助 TL;博士:
- 到
template.render()
- 在将呈现的unicode结果写入文件之前,将其编码为bytestring
index_file.write(
template.render(index_variables)
)
在一条语句中,这基本上只是Python关注的一行,因此您得到的回溯是误导性的:我在重新创建测试用例时得到的异常不是发生在template.render(index\u variables)
中,而是发生在index\u file.write()
中。所以像这样把代码分解
output = template.render(index_variables)
index_file.write(output)
是诊断UnicodeEncodeError发生的确切位置的第一步
Jinja返回unicode,然后让它呈现模板。因此,在将结果写入文件之前,需要将其编码为bytestring:
index_file.write(output.encode('utf-8'))
第二个错误是将一个由testring编码的utf-8
传递到template.render()
-。因此,假设您的myvar
包含UTF-8,您需要首先将其解码为unicode:
index_variables['title'] = myvar.decode('utf-8')
所以,总而言之,这对我来说很有用:
# -*- coding: utf-8 -*-
from jinja2 import Environment, PackageLoader
env = Environment(loader=PackageLoader('myproject', 'templates'))
# Make sure we start with an utf-8 encoded bytestring
myvar = 'Séptimo Cine'
index_variables = {'title':''}
# Decode the UTF-8 string to get unicode
index_variables['title'] = myvar.decode('utf-8')
template = env.get_template('index.html')
with open("index_file.html", "w") as index_file:
output = template.render(index_variables)
# jinja returns unicode - so `output` needs to be encoded to a bytestring
# before writing it to a file
index_file.write(output.encode('utf-8'))
如果因为混合了多种语言(如我的例子)而没有任何效果,只需将“utf-8”替换为“utf-16” 此处的所有编码选项:
在脚本开头添加以下行,它将正常工作,无需进一步更改:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
reload(sys)
sys.setdefaultencoding("utf-8")
Python中的字符串是二进制字符串。要使用unicode,请使用:astring.decode('urf-8')。或者使用:从未来的导入unicode_Literal我确实尝试在呈现模板后添加编码(“utf-8”),但这还不够。只有在写入文件时,才需要将其编码回
utf-8
。这个答案当然有帮助。谢谢你详细的回答并指出我的错误。它现在可以工作了:)非常感谢。你为我节省了很多时间。在我的情况下,我正在打印到标准输出,我的错误是:文件。。。print template.render(context=getContent(..)UnicodeEncodeError:“latin-1”编解码器无法对1064-1088位置的字符进行编码:序号不在范围内(256)
在尝试解决“getContent”调用中的问题30分钟后,我找到了您的答案,这突出表明问题在于打印!不要这样做。请不要传播这个。由于某种原因,sys
模块上的此设置不可用;这是一个全局设置,任何依赖于隐式编码或解码的代码都会引发非ASCII文本异常,并因此而中断。这包括第三方库中的代码。我非常了解这篇文章,强烈反对。你有没有看到我的答案也贴在那里?这仍然是一个货物崇拜,每当一个UnicodeEncoding例外事件抬头时就会出现。这不是解决办法。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
reload(sys)
sys.setdefaultencoding("utf-8")