2012-06-06 63 views
3

下面的代码工作正常:打印非ASCII字符

from jinja2 import Template 

mylist = ['some text \xc3'] 

template = Template('{{ list }}') 

print template.render(list=mylist) 

当我运行它,它输出:

['some text \xc3'] 

然而,当我尝试打印的实际列表元件,它失败:

template = Template('{{ list[0] }}') 

print template.render(list=mylist) 

错误是:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 10: ordinal not in range(128) 

我想找到一种方法来打印单个列表元件以相同的方式,整个列表打印,其中,所述非ASCII字符表示与\ X表示法。

回答

0

我想通了。关键是要做到str.encode('string-escape')

所以,我这样做:

template = Template('{{ list[0].encode("string-escape") }}') 

和起作用的。

+0

这是一种糟糕的方法,您应该在渲染前执行任何解码/编码,而不是将此任务委托给模板。我认为''字符串转义'可能不是正确的编码。你的原始输入数据是什么? – schlamar

+0

原始输入数据来自未知来源(网络数据),我不在乎打印时的外观。我只是不想在忍者中出错。 至于在模板中进行编码,我认为这是完全合适的,因为字符串的编码是在视图的域中,这是模板的用途。此外,我在这里给出了一个简单的例子,但是在实际数据中,要编码的项目是较大数据结构的一部分,这将花费不必要的处理时间来额外传递以对值进行预编码。 – chaimp

+0

您将在问题中注意到,当我打印整个列表对象时,我正在寻找一种使其以与字符串打印相同的方式进行打印的方法。这个解决方案似乎正是这样做的。 因此,如果您在我自己的问题的答案中删除倒票,我想我会回答我的问题。否则,请提出一个我感兴趣的替代解决方案。 – chaimp

2

你永远不应该打开一个编码的文件,不解码它。

您应该从curl中读取编码(例如,使用-i-H选项),并解析HTTP标头或输出文件(如果未在标头中指定编码)。

或者作为卷曲的替代方法,您可以使用不需要写入文件的requests库。获取网络资源的样子:

>>> r = requests.get('http://python.org') 
>>> r.content 
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML... 

content已编码的HTTP规范以下。

作为最后一种方法,您可以猜测编码并替换未知的字符。这将是最容易实施的解决方案。例如:

with codecs.open(filename, encoding='utf-8', errors='replace') as fobj: 
    ... 

您的方法总是会丢失信息(如果没有ascii字符)。我的前两种方法从不,最后一种只有在猜测编码错误的情况下。

3

Jinja docs

“ Jinja2的是使用Unicode内部,这意味着你必须通过Unicode对象,以渲染功能或字节串,仅由ASCII字符”

mylist = [u'some text \xc3'] 
+0

在那种情况下,我如何将非ASCII字符转换为ASCII码?我有这个城市名称'AlGhaţghaţ',我无法在忍者模板中打印! –

0

jla适合我的情况。

我使用utf-8作为python源文件,所以用u前缀解决了我的问题。