2

我正在编写脚本来清理 unicode 文本文件(存储为 UTF-8),我选择使用 Python 3.x(3.2)而不是更流行的 2.x,因为 3.x 应该默认为 UTF- 8. 也许我做错了什么,但似乎打印语句至少仍然没有默认为 UTF-8。如果我尝试打印一个包含特殊字符的字符串(下面的 msg 是一个字符串),我仍然会收到这样的 UnicodeEncodeError:

print(label, msg)
... in encode
    return codecs.charmap_encode(input,self.errors,encoding_map)[0] 
UnicodeEncodeError: 'charmap' codec can't encode character '\u0968' in position
38: character maps to <undefined>

如果我首先使用 encode() 方法(很好地默认为 UTF-8),我可以避免错误:

print(label, msg.encode())

这也适用于打印包含 unicode 字符串的对象或列表——这是我在调试时经常要做的事情——因为 str() 似乎默认为 UTF-8。但是我真的需要记住每次我想做 print(myobj) 时都使用 print(str(myobj).encode()) 吗?如果是这样,我想我可以尝试用我自己的函数包装它,但我对处理 print() 支持的所有参数排列没有信心。

此外,我的脚本从文件加载正则表达式并一一应用它们。在应用 encode() 之前,我能够在控制台上打印一些相当清晰的内容:

msg = 'Applying regex {} of {}: {}'.format(i, len(regexes), regex._findstr)
print(msg)

Applying regex 5 of 15: ^\\ge[0-9]*\b([ ]+[0-9]+\.)?[ ]*

但是,如果正则表达式包含文字 unicode 字符,则会崩溃,因此我首先将 encode() 应用于字符串。但是现在正则表达式很难在屏幕上阅读(我怀疑如果我尝试编写将这些正则表达式保存回磁盘的代码,我可能会遇到类似的问题):

msg = 'Applying regex {} of {}: {}'.format(i, len(regexes), regex._findstr)
print(msg.encode())

b'Applying regex 5 of 15: ^\\\\ge[0-9]*\\b([ ]+[0-9]+\\.)?[ ]*'

我在 Python 方面还不是很有经验,所以我可能会误解。任何解释或教程链接(对于 Python 3.x;我在网上看到的大部分内容都是针对 2.x)将不胜感激。

4

2 回答 2

6

print不默认使用任何编码,它只是使用输出设备(如控制台)声称支持的任何编码。您的控制台编码似乎是非 unicode,因此print尝试使用该编码对您的 unicode 字符串进行编码,但失败了。解决这个问题的最简单方法是告诉控制台使用 utf8(就像export LC_ALL=en_US.UTF-8在 unix 系统上一样)。

于 2012-08-16T09:25:51.070 回答
2

更简单的方法是仅在脚本中使用 unicode,并且仅在您想与“外部”世界交互时使用编码数据。也就是说,当您有要解码的输入或要编码的输出时。

为此,每次阅读时使用decode,每次输出时使用encode

对于您的正则表达式,请使用re.UNICODE标志。

我知道这并不能完全逐点回答您的问题,但我认为应用这种方法应该可以让您免受编码问题的影响。

于 2012-08-16T09:09:37.620 回答