【问题标题】:UnicodeEncodeError when printing from Django从 Django 打印时出现 UnicodeEncodeError
【发布时间】:2014-01-06 20:43:10
【问题描述】:

使用python解释器

>>> print u'\xe9'
é

但是如果我将同一行放在 Django 视图中,我会得到

UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 0: 
ordinal not in range(128)

这是为什么呢?

我正在使用 Django 1.5.1 和 python 2.6.6。

一些背景... 我有一个 Django 项目,它使用 3rd 方模块来处理一些字符串,并打印它们。在 Django 之外使用该模块时,它工作正常,但是当它作为 Django 项目的一部分使用时,它在尝试打印非 ascii 字符时崩溃。我真的不关心打印,只关心它正在做的其他事情。

【问题讨论】:

  • 它在哪里打印字符以及它在哪里失败?
  • 抱歉,我不确定我是否理解您的问题。在 Django 视图中执行 print u'\xe9' 会导致异常。
  • 但问题是,为什么要在视图中打印?通常在您输出到响应的视图中。
  • 正如我上面所写的,我正在使用第 3 方模块(由视图调用)来进行打印。

标签: python django unicode character-encoding django-views


【解决方案1】:

Python print 语句会自动将 Unicode 值编码为用于sys.stdout 的编解码器。

在您的控制台或终端中,输出编解码器会自动从系统中获取。但是,如果您的输出被重定向到 文件,则使用默认编解码器 ASCII

在服务器上运行的 Django 应用程序不能依赖将输出编解码器设置为可以处理所有 unicode 代码点的东西。不要使用print,而是使用日志记录,并显式编码。

如果第三方库正在这样做,您需要联系维护人员并要求他们停止这样做。您可以使用上下文管理器包装对该库的每个调用,该上下文管理器将sys.stdout 替换为一个虚拟对象(具有合适的.encoding 属性的对象),但这实际上只是权宜之计:

from contextlib import contextmanager
from io import BytesIO
import sys

@contextmanager
def capture_stdout_unicode(codec='UTF-8'):
    output = BytesIO()
    output.encoding = codec
    orig, sys.stdout = sys.stdout, output
    try:
        yield output
    finally:
        sys.stdout = orig

然后像这样使用:

with capture_stdout_unicode() as out:
    api_call_that_prints()

logger.info(out.getvalue())

【讨论】:

  • 优秀。谢谢你。抱歉,我无法投票赞成您的回答 - 我还没有足够的声誉 :-)
  • 没问题,我今天已经达到了声望上限。 :-)
猜你喜欢
  • 2017-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-05
相关资源
最近更新 更多