由于打印'生产时出现Unicode错误为什么?

时间:2016-01-29 23:41:09

标签: python django heroku unicode

好的,我只想了解。经过1个多小时的调试入口点后,在使用Postman对api进行了十几次不同的测试并确保它在本地再次运行之后,在生产中出现了一个奇怪的this.data.items[i].items2[0].result2; 错误。我发现如果删除print语句,它就可以了。

这是我的切入点的相关代码:

Unicode

所以...当我打印这样的字典时:

@csrf_exempt
def create_books(request):

    sent_json = request.body

    if not sent_json:
        return HttpResponse("No json in request.body", status=404)

    sent_json = json.loads(sent_json)
    books = sent_json['books']

    print "books: %s" % books
    for num, book in books.iteritems():
        title = book['title']
        writer = book['writer']
        if Book.objects.filter(titulo=title, writer=writer).exists():
            book = Book.objects.get(titulo=title, writer=writer)
        else:
            book = Book.objects.create(titulo=title, writer=writer)

        print "book.title: %s" % book.title  # !!! ERROR

一切都很好,但是当我打印 print "books: %s" % books

book.title

我收到了Unicode错误。导致错误的标题当然包含在书籍词典中。但是为什么它在保存到数据库并作为对象的属性调用后会出错?

删除第二张照片后,一切都解决了。但我不明白。

3 个答案:

答案 0 :(得分:0)

TLDR:要解决此问题,您需要在将字符串传递给print之前对其进行编码:

print "book.title: %s" % book.title.encode('utf-8')

答案:

books返回的repr(books)代表(在print "books: %s" % books中自动使用)没有任何"特殊" (非ascii)字符,因为repr()会正确缩放它们。但在这种情况下,book.titlerepr()将不会被使用。

如果您将unicode对象传递给print,则会尝试将其编码为sys.stdout.encoding上的编码(如果已检测到),如果未检测到则编码为ascii。最好的方法是在通过软件边界发送数据之前始终对数据进行编码。

答案 1 :(得分:0)

问题是book.title中的unicode字符串无法编码到您的终端。您可以在sys.stdout.encoding查看终端编码,看看它是什么。

假设我有一个unicode标题(可能在浏览器中显示或未正确显示)...

>>> title = u"ༀ༁༂༃༄༅༆༇༈༉༊"
>>> book = { 'title':title }

如果我打印book,我会得到一个字典的字符串表示,它不会尝试编码unicode字符串

>>> print "%s" % book
{'title': u'\u0f00\u0f01\u0f02\u0f03\u0f04\u0f05\u0f06\u0f07\u0f08\u0f09\u0f0a'}

但是如果我直接打印字符串,字符串将被编码到本地终端

>>> print "%s" % title
ༀ༁༂༃༄༅༆༇༈༉༊

它适用于我,但你的字符串失败了。您可以通过自己进行解码并为不可打印的字符设置策略来解决问题

>>> print "%s" % title.encode(sys.stdout.encoding, 'replace')
ༀ༁༂༃༄༅༆༇༈༉༊

这一切对我来说仍然有效,因为我有一个utf-8终端,但你应该在那里看到问号。

答案 2 :(得分:0)

dictlist等容器在打印期间调用repr()项目str(),因此您不会看到任何Unicode错误:{ {1}}转义不可打印(Python 2上的非ascii)字符:

repr()

不要在>>> print u"\N{EURO SIGN}" € >>> print [u"\N{EURO SIGN}"] # container (list) calls repr(u"€") [u'\u20ac'] >>> print repr(u"\N{EURO SIGN}") u'\u20ac' 次电话中撒上您的代码; 直接打印Unicode 。如果它导致Unicode错误然后修复环境,例如,配置您的区域设置(默认为您不想要的C(ascii)),请参阅LANG,LC_CTYPE,LC_ALL envvars和/或.encode() envvar(和/或在Windows上安装PYTHONIOENCODING。参见:

相关问题