【问题标题】:Printing escaped Unicode in Python在 Python 中打印转义的 Unicode
【发布时间】:2012-01-04 13:13:46
【问题描述】:
>>> s = 'auszuschließen'
>>> print(s.encode('ascii', errors='xmlcharrefreplace'))
b'auszuschließen'
>>> print(str(s.encode('ascii', errors='xmlcharrefreplace'), 'ascii'))
auszuschließen

有没有更漂亮的方法来打印没有b'' 的任何字符串?

编辑:

我只是想从 Python 打印转义字符,我唯一的抱怨是当我这样做时 Python 添加了“b''”。

如果我想在像 Windows 7 这样的哑终端中看到实际角色,那么我会得到这个:

Traceback (most recent call last):
  File "Mailgen.py", line 378, in <module>
    marked_copy = mark_markup(language_column, item_row)
  File "Mailgen.py", line 210, in mark_markup
    print("TP: %r" % "".join(to_print))
  File "c:\python32\lib\encodings\cp437.py", line 19, in encode
    return codecs.charmap_encode(input,self.errors,encoding_map)[0]
UnicodeEncodeError: 'charmap' codec can't encode character '\u2026' in position 29: character maps to <undefined>

【问题讨论】:

  • 你为什么不直接使用print(s)?为什么需要编码为ascii?
  • 因为我不认为我的终端支持我的代码处理的每一个奇怪的字符。
  • print(str(s.encode('ascii', errors='ignore'), 'ascii')) 会更漂亮,无论如何。
  • 我已经更新了我的答案。虽然这回答了你的问题,但它有一种实际上解决了错误问题的感觉。我脑海中浮现的问题是,为什么您想要“漂亮”输出本质上是调试信息(字符串中的 Unicode 字符)。这个日志是应该提供给另一个程序的实际程序用户界面或标准输出输出,还是......?
  • 您也可以设置环境变量PYTHONIOENCODING=cp437:backslashreplace,然后使用print(s)。我没有在答案中提到它,因为python might crash if you set it incorrectly.

标签: python python-3.x


【解决方案1】:
>>> s='auszuschließen…'
>>> s
'auszuschließen…'
>>> print(s)
auszuschließen…
>>> b=s.encode('ascii','xmlcharrefreplace')
>>> b
b'auszuschlie&#223;en&#8230;'
>>> print(b)
b'auszuschlie&#223;en&#8230;'
>>> b.decode()
'auszuschlie&#223;en&#8230;'
>>> print(b.decode())
auszuschlie&#223;en&#8230;

您从 Unicode 字符串开始。将其编码为 ascii 会创建一个带有所需字符的 bytes 对象。 Python 不会在不将其转换回字符串的情况下打印它,并且默认转换会放入 b 和引号中。使用decode 将其显式转换回字符串;默认编码是utf-8,因为你的bytes 只包含ascii,它是utf-8 的一个子集,所以保证可以工作。

【讨论】:

  • 这是迄今为止最优雅的解决方案。请注意,我的终端会默默地将 '...' 变成 '.'
【解决方案2】:

查看 ascii 表示(如 Python 2 上的 repr())以进行调试:

print(ascii('auszuschließen…'))
# -> 'auszuschlie\xdfen\u2026'

打印字节:

sys.stdout.buffer.write('auszuschließen…'.encode('ascii', 'xmlcharrefreplace'))
# -> auszuschlie&#223;en&#8230;

【讨论】:

  • 仔细检查,在我的终端 sys.stdout.buffer.write('auszuschließen...test'.encode('ascii', 'xmlcharrefreplace')) 打印:auszuschließen.test24 I不喜欢特殊情况(打印未捕获的返回值),所以我将使用 decode() 解决方案。
  • @Cees Timmerman: no, it is not. 你可能会将它与交互式解释器混淆,例如 ipython、bpython、idle 或只是没有参数的 python。在这种情况下,您不需要打印字符串;解释器自己回显它的值。
  • @J.F.Sebastian:是的。关键是他想在没有 b'' 的情况下打印。使用 ascii 只打印不带 b,但保留 ''。
  • @J.F.Sebastian: 我的意思是 >>> sys.stdout.buffer.write('auszuschließen.test'.encode('ascii', 'xmlcharrefrep lace')) auszuschließen.test24
【解决方案3】:

并非所有终端都能处理超过某种 8 位字符集,这是真的。但不管你做什么,他们都不会处理,真的。

假设您的操作系统设置正确地设置终端,打印 Unicode 字符串会产生可能的最佳结果,这意味着终端无法打印的字符将被替换为某些字符,例如问号或类似字符.自己做翻译并不会真正改善事情。

更新:

由于您想知道字符串中有哪些字符,因此您实际上想知道它们的 Unicode 代码,或者在这种情况下对应的 XML。这比打印更多检查,然后通常 b'' 部分本身不是问题。

但是你可以像这样轻松地摆脱它:

print(repr(s.encode('ascii', errors='xmlcharrefreplace'))[2:-1])

【讨论】:

  • Traceback(最近一次调用最后一次):文件“Mailgen.py”,第 378 行,在 中标记_copy = mark_markup(language_column, item_row) 文件“Mailgen.py”,第 210 行,在 mark_markup print("TP: %r" % "".join(to_print)) 文件“c:\python32\lib\encodings\cp437.py”,第 19 行,编码返回 codecs.charmap_encode(input,self.errors,encoding_map )[0] UnicodeEncodeError: 'charmap' codec can't encode character '\u2026' in position 29: character maps to
  • @CeesTimmerman:看,你有一个实际问题的开始。你应该做一个。还包括有关您的终端的信息。
  • 好的:我如何在 64 位 Windows 7 企业命令终端(最好是任何其他终端)中以 Python 方式打印未知的 Unicode 字符串?
  • @CeesTimmerman 您应该使用您在第一条评论中指定的详细信息更新您的原始问题(如果与此问题完全不同,请提出 new 问题);这将改善问题并让更多人有机会帮助您。
【解决方案4】:

由于您使用的是 Python 3,因此您可以将print(s) 写入控制台。

我同意,根据控制台的不同,它可能无法正确打印,但我想自 2006 年以来的大多数现代操作系统都可以处理 Unicode 字符串而不会出现太大问题。我鼓励你试一试,看看它是否有效。

或者,您可以通过将其放在文件中的任何行之前来强制编码(类似于shebang):

# -*- coding: utf-8 -*-

这将强制解释器将其呈现为 UTF-8。

【讨论】:

  • 这个 64 位 Windows 7 企业命令终端的副本,一方面,不喜欢打印不在 CP437 中的字符,例如'\u2026'.
  • 1. # -*- coding: utf-8 -*- 是 Python3 2 的默认设置。它不会改变 print(s) 的工作方式。它只影响文字字符串的解释方式。
猜你喜欢
  • 2016-08-29
  • 2017-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-23
相关资源
最近更新 更多