为什么只有在传递Python脚本的输出时才会出现unicode错误?

时间:2018-06-20 13:48:55

标签: python shell unicode pipe python-unicode

我使用以2.7(seafile-cli,来自文件同步解决方案Seafile)编写的Python脚本。

我知道unicode is problematic in Python 2,但幸运的是,在启动脚本时正确处理了带有变音符号的文件名:

$ # seaf-cli status
# Name  Status  Progress
photos  downloading     0/0, 0.0KB/s
Ma bibliothèque downloading     566/1770, 1745.7KB/s
videos  downloading     28/1203, 5088.0KB/s
dev-perso       downloading     0/0, 0.0KB/s
dev-pro downloading     0/0, 0.0KB/s

令我惊讶的是,在传递此输出时,Python脚本以UnicodeEncodeError崩溃:

$ seaf-cli status | cat -
# Name  Status  Progress
photos  downloading     0/0, 0.0KB/s
Traceback (most recent call last):
  File "/usr/bin/seaf-cli", line 845, in <module>
    main()
  File "/usr/bin/seaf-cli", line 841, in main
    args.func(args)
  File "/usr/bin/seaf-cli", line 649, in seaf_status
    tx_task.rate/1024.0)
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe8' in position 11: ordinal not in range(128)

虽然我知道它最初可能与Ma bibliothèque出现问题(但没有),但为什么管道传输会触发回溯?

那不是shell的问题吗? -输出此时已“离开”脚本。

编辑:answeranother question中。标记为重复。

1 个答案:

答案 0 :(得分:0)

Python知道如何在程序内部处理编码,因为它使用了终端应用程序正在使用的任何编码。

发送(管道传输)输出时,需要对其进行编码。这是因为使用管道实际上在应用程序之间发送字节流。每个管道都是单向通道,一侧写入数据,另一侧读取数据。

使用管道或重定向,您正在将数据发送到fd,该数据由另一个应用程序读取。

因此,您需要确保Python在发送数据之前正确地对数据进行编码,然后输入程序需要在处理之前解码

您也可能会发现此question有用


更新:我将尝试详细说明编码。我的答案的第一行是因为您的Python解释器使用特定的编码,所以它知道如何将六进制值(实际字节)转换为符号。

我的口译员没有;如果我尝试根据您的文本创建字符串-我会收到错误消息:

>>> s = 'bibliothèque'
Unsupported characters in input

这是因为我在解释器上使用了不同的编码。

您的外壳使用与Python解释器不同的编码。当Python从程序中发送数据时,它使用默认编码:ASCII。它无法使用ASCII转换您的特殊字符(由十六进制值\ xe8显示)。因此,您必须指定要使用哪种编码,以便Python发送。

如果更改外壳程序编码,您也许可以克服这一点-选中此question on SO

PS -Ned Batchelder在youtube上有一段关于Unicode的精彩视频-也许这将为这个主题提供更多启示。