【问题标题】:Printing non-ascii characters in python/jinja在 python/jinja 中打印非 ascii 字符
【发布时间】:2012-06-06 05:47:21
【问题描述】:

以下代码正常工作:

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 表示法表示。

【问题讨论】:

    标签: python jinja2 non-ascii-characters


    【解决方案1】:

    来自Jinja docs

    “Jinja2 在内部使用 Unicode,这意味着您必须将 Unicode 对象传递给渲染函数或仅由 ASCII 字符组成的字节串。”

    mylist = [u'some text \xc3']
    

    【讨论】:

    • 在这种情况下,如何将非 ascii 字符转换为 ascii ?我有这个城市名称Al Ghaţghaţ,我无法在 jinja 模板中打印!
    【解决方案2】:

    您永远不应该打开编码文件而不对其进行解码。

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

    或者作为 curl 的替代方案,您可以使用不需要写入文件的 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】:

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

      所以,我这样做了:

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

      这很有效。

      【讨论】:

      • 这是一种不好的方法,您应该在渲染之前进行任何解码/编码,并且不要将此任务委托给模板。而且我认为'string-escape' 可能不是正确的编码。你的原始输入数据是什么?
      • 原始输入数据来自未知来源(网络数据),我不在乎它打印时的样子。我只是不想在 jinja 中出错。至于在模板中进行编码,我认为这是非常合适的,因为字符串的编码在 View 的域中,这就是模板的用途。此外,我在这里举了一个简单的例子,但是在实际数据中,要编码的项目是更大数据结构的一部分,这将花费不必要的处理时间来进行额外的传递以对值进行预编码。
      • 您会在问题中注意到,当我打印整个列表对象时,我正在寻找一种方法来使其以与字符串打印相同的方式打印。该解决方案似乎正是这样做的。因此,如果您取消对我自己对我的问题的回答的反对票,我将不胜感激,我认为这完美地回答了我的问题。否则,请提出我感兴趣的替代解决方案。
      • 如果您获取网络数据,您应该在输入步骤直接对其进行编码。您可以从 HTTP 响应标头中读取编码并手动解码,也可以使用更高级别的库,例如 requests(强烈推荐!),它会自动执行此操作。有问题的一点是,例如,如果 char ö 打印在列表中,它将看起来像 u'\xf6'(因为在那里你会看到字符串的 repr)。但是,如果您将其打印为该列表的元素,则它应该是ö。您的方法是错误的,并没有解决问题的真正原因,即输入。
      • 更新您的问题,您实际上是如何获得输入的,因为这需要作为真正的解决方案进行修复,然后我或其他人可以进一步帮助您。
      【解决方案4】:

      jla 适合我的情况。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-12-14
        • 2021-05-21
        • 1970-01-01
        • 2013-11-19
        • 2015-09-14
        • 2012-10-14
        • 1970-01-01
        • 2017-08-11
        相关资源
        最近更新 更多