1

我已经筛选了很多很多 python/unicode 解释,但我似乎无法理解这一点。

情况如下:

我正在从 reddit 中提取大量评论(制作一个机器人),并希望主要将它们存储在 MongoDB 中,但还需要能够打印出评论树以便手动检查正在发生的事情。

到目前为止,我将评论放入数据库没有任何问题,但是当我尝试打印到标准输出时,CP1252 字符集遇到了它显然不支持的字符的问题。

正如我所读到的,在 Python 3 中,内部的所有内容(字符串)都存储为 Unicode,输入和输出必须是字节,所以这很好 - 我可以将 unicode 编码为 CP1252,在几种情况下我会看到 \ x** 我不介意的字符 - 我猜它们代表超出范围的字符?

问题是我正在使用 \n (换行符)和制表符打印出注释树(到标准输出),因此很容易查看,但显然当您使用换行符转义序列对 unicode 字符串进行编码时,它会将它们转义因此它们被打印为文字.

以下是我的编码语句供参考:

encoded = post.tree_to_string().encode('cp1252','ignore')

谢谢

编辑:

我想要的是

|Parent Comment

    |Child comment 1

        |GChild comment 1

    |Child comment 2

|Parent Comment 2

我得到的是

b"\n|Parent comment \n\n |Child comment \n\n etc
4

3 回答 3

2

打印到控制台时,Python 将自动以控制台的编码(cp437在美国 Windows 上)对字符串进行编码,并对控制台编码不支持的任何字符引发异常。例如:

#!python3
#coding: utf8
print('Some text\nwith Chinese 美国\ncp1252 ÀÁÂÃ\nand cp437 ░▒▓')

输出:

Traceback (most recent call last):
  File "C:\test.py", line 5, in <module>
    print('Some text\nwith Chinese \u7f8e\u56fd\ncp1252 \xc0\xc1\xc2\xc3\nand cp437 ░▒▓')
  File "C:\Python33\lib\encodings\cp437.py", line 19, in encode
    return codecs.charmap_encode(input,self.errors,encoding_map)[0]
UnicodeEncodeError: 'charmap' codec can't encode characters in position 24-25: character maps to <undefined>

要更改此默认值,您可以更改stdout以显式指定编码以及如何处理错误:

#!python3
#coding: utf8
import io,sys
sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding=sys.stdout.encoding,errors='replace')
print('Some text\nwith Chinese 美国\ncp1252 ÀÁÂÃ\nand cp437 ░▒▓')

输出(到 cp437 控制台):

Some text
with Chinese ??
cp1252 ????
and cp437 ░▒▓

您也可以stdout通过直接写入其buffer接口来显式执行此操作而无需更改:

sys.stdout.buffer.write('Some text\nwith Chinese 美国\ncp1252 ÀÁÂÃ\nand cp437 ░▒▓'.encode('cp437',errors='replace'))

第三种选择是在启动 Python 之前设置以下环境变量,这将与解决方案stdout类似TextIOWrapper

PYTHONIOENCODING=cp437:replace

最后,由于您还提到了写入文件,所以查看您正在写入的所有字符的最简单方法是使用 UTF-8 作为文件的编码:

#!python3
#coding: utf8
with open('out.txt','w',encoding='utf8') as f:
    f.write('Some text\nwith Chinese 美国\ncp1252 ÀÁÂÃ\nand cp437 ░▒▓')
于 2013-10-06T16:48:09.493 回答
0

在 python3 中打印不需要将字符串编码为字节,只需让你的 stdout(console) 成为一个 unicode 环境......

print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)

于 2013-10-06T15:08:55.640 回答
0

我不知道我是否正确理解了您的问题,但是您不能在打印到标准输出之前删除换行符和制表符吗?

print(re.sub('[\t\n]', ' ', post.tree_to_string()))

您还可以告诉 Python 删除所有控制字符,如此所述。

于 2013-10-06T14:40:41.053 回答