【问题标题】:Inconsistent output of unicode box-drawing characters in python IDLEpython IDLE中unicode box-drawing字符的输出不一致
【发布时间】:2015-08-11 15:16:29
【问题描述】:

我有以下代码:

# -*- coding: utf-8 -*-
print "╔╤╤╦╤╤╦╤╤╗"
print "╠╪╪╬╪╪╬╪╪╣"
print "╟┼┼╫┼┼╫┼┼╢"
print "╚╧╧╩╧╧╩╧╧╝"
print "║"
print "│"

由于某种原因,只有第三行 (╚╧╧╩╧╧╩╧╧╝) 实际输出正确,其余的是奇怪的符号组合。我认为这是由于一些编码问题。 IDLE中的完整输出如下:

╔╤╤╦╤╤╦╤╤╗
╠╪╪╬╪╪╬╪╪╣
╟┼┼╫┼┼╫┼┼╢
╚╧╧╩╧╧╩╧╧╝
â•‘
│

这是什么原因造成的,我该如何解决?我正在使用只有触摸键盘的平板电脑(带有 Win10 的 Surface Pro 3),因此任何打字量最少的解决方案(尤其是输入奇怪的字符)都是理想的,但显然所有帮助都值得赞赏。

【问题讨论】:

  • 这一定是本地问题,因为它在这里的 *nix 系统上运行良好,本地和远程。 ideone.com/DeanM5
  • 我可能疯了,但你不需要在 Python 2 中为 unicode 字符串添加前缀吗?例如,print u"╠╪╪╬╪╪╬╪╪╣"。见docs.python.org/2/howto/…
  • @FredLarson 没有“u”,字符串只是 UTF-8 字节流,在传递到终端之前不需要进一步编码。
  • @FredLarson 谢谢,解决了!我想知道为什么第 3 行运行良好...
  • @chepner: 是的,但是 UTF-8 字节流在 Windows 上可以工作吗?我相信 Windows 原生使用 UTF-16。

标签: python unicode character


【解决方案1】:

Mojibake 表示以一种编码方式编码的文本以另一种不兼容的编码方式显示:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
print(u"╔╤╤╦╤╤╦╤╤╗".encode('utf-8').decode('cp1252')) #XXX: DON'T DO IT
# -> ╔╤╤╦╤╤╦╤╤╗

有几个地方可能使用了错误的编码。

# coding: utf-8 编码声明说明应该如何解释您的源代码中的非ascii字符(例如,在字符串literals中)。如果 print u"╔╤╤╦╤╤╦╤╤╗" 在您的情况下有效,则意味着源代码本身已正确解码为 Unicode。对于调试,您可以仅使用 ascii 字符编写字符串:u'\u2554\u2557' == u'╔╗'

print "╔╤╤╦╤╤╦╤╤╗"(不要这样做)按原样打印字节(在这种情况下使用 utf-8 编码的文本)。 IDLE 本身适用于 Unicode (BMP)。字节必须先解码为 Unicode 文本,然后才能在 IDLE 中显示。似乎 IDLE 使用诸如 cp1252 (locale.getpreferredencoding(False)) 之类的 ANSI 代码页来解码 Windows 上的输出字节。不要将文本打印为字节。在任何使用与您的源代码不同的字符编码的环境中,它都会失败,例如,如果您在使用 cp437 OEM 代码页的 Windows 控制台中运行问题中的代码,您将得到 ΓòöΓòù... mojibake。

您应该对程序中的所有文本使用 Unicode。 Python 3 甚至禁止在 bytes 文字中使用非 ascii 字符。你会在那里得到SyntaxError

print(u'\u2554\u2557') 可能会因UnicodeEncodeError 而失败,如果您将在 Windows 控制台中运行代码并且 cp437 等 OEM 代码页无法表示字符。 To print arbitrary Unicode characters in Windows console, use win-unicode-console package。如果您使用 IDLE,则不需要它。

【讨论】:

    【解决方案2】:

    根据@FredLarson 的建议,在字符串之前加上一个 u 来解决问题:

    print u"╔╤╤╦╤╤╦╤╤╗"
    print u"╠╪╪╬╪╪╬╪╪╣"
    print u"╟┼┼╫┼┼╫┼┼╢"
    print u"╚╧╧╩╧╧╩╧╧╝"
    print u"║"
    print u"│"
    

    确切的原因仍然未知,因为它似乎在其他系统上也能正常工作,奇怪的是第三行工作正常。

    【讨论】:

    • 这里涉及三个步骤: 1)文件本身包含字符的UTF-8编码。它们显示为画框字符,因为您的编辑器理解 UTF-8 并将其解码以供显示。 2)u"..." 告诉 Python 创建 Unicode 对象,这意味着 UTF-8 被解码为适当的代码点,这些代码点(内部)被重新编码以存储在内存中。 3) 输出时,Unicode 字符串会自动重新编码为 UTF-8 以显示在终端上。
    • @chepner:这是不正确的。 (1) 文件(错误地)可能包含使用其他字符编码编码的字符,例如,如果您在 Windows 控制台中键入它,则可能会使用 cp437 (OEM cp)。 (2) Python 使用coding: 声明中指定的编码来解码u"..." 文字。在这种情况下它是 utf-8,但它可以是其他一些编码。 (3) 输出使用什么编码取决于脚本的运行方式/位置。问题表明IDLE uses cp1252 to decode the output bytes in this case。它可能会跳过 Unicode 的重新编码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-31
    相关资源
    最近更新 更多