Python 3和Unicode - 如何打印换行符(理解这一点的一般问题)

时间:2013-10-06 13:59:11

标签: python unicode encoding

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

情况如下:

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

到目前为止,我没有任何问题将注释放入数据库,但是当我尝试打印到stdout时,CP1252字符集遇到字符问题,显然它不支持。

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

问题是我使用\ n(换行符)和制表符打印出注释树(到stdout),因此很容易查看,但显然当你使用换行符转义序列编码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

3 个答案:

答案 0 :(得分:2)

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

#!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 ░▒▓')

答案 1 :(得分:0)

我不知道我是否正确理解了你的问题,但是你不能在打印到stdout之前删除换行符和标签吗?

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

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

答案 2 :(得分:0)

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

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