为什么python3k的pyserial返回字节而python2k返回字符串?

时间:2014-10-23 07:40:34

标签: python python-2.7 python-3.x pyserial

我正在尝试移植 https://github.com/thearn/Python-Arduino-Command-API到python 3,到目前为止我已经达到了可以无误地导入它的程度,我试图运行blink示例found here并且我总是会遇到类型错误。

我想我已经把它缩小到了这个范围。

PySerial 2.7 for python 2.7.8的readline函数返回一个字符串,PySerial 2.7 for python 3.3的readline函数返回字节。

Python 2

>>> import serial
>>> serial.VERSION
'2.7'
>>> ser= serial.Serial(port='COM4')
>>> ser.readline()
'0\r\n'
>>> type(ser.readline())
<type 'str'>

Python 3

>>> import serial
>>> serial.VERSION
'2.7'
>>> ser = serial.Serial(port='COM4')
>>> ser.readline()
b'0\r\n'
>>> type(ser.readline())
<class 'bytes'>

我已经检查了pyserial的python 2和python 3实现的readline函数的来源,看起来它们都应该返回字节,因为每个字符串的最后一行是return bytes(line),这就是唯一的返回语句在整个功能中。

我的问题:为什么PySerial 2.7的readline函数在python2和python3中返回不同的结果?

3 个答案:

答案 0 :(得分:4)

这是因为在Python 3.x中,文本始终是Unicode并且由str类型表示,而二进制数据由字节类型表示。此功能与Python 2.x版本不同。

在您的示例中,ser.readline()实际上返回二进制数据。

答案 1 :(得分:1)

这是Python 2和3之间的主要区别之一。

来自https://docs.python.org/3.0/whatsnew/3.0.html

  

Python 3.0使用文本和(二进制)数据的概念,而不是Unicode字符串和8位字符串。所有文本都是Unicode;但编码的Unicode表示为二进制数据。用于保存文本的类型是str,用于保存数据的类型是字节。与2.x情况的最大区别在于,任何在Python 3.0中混合文本和数据的尝试都会引发TypeError,而如果您要在Python 2.x中混合使用Unicode和8位字符串,那么如果8位字符串碰巧只包含7位(ASCII)字节,但如果包含非ASCII值,则会得到UnicodeDecodeError。这种特定价值的行为多年来引起了许多悲伤的表情。

您可以在上面链接的“文本与数据而不是Unicode与8位”部分找到完整的解释。

答案 2 :(得分:1)

在python 3中执行套接字程序时出现了这个问题。当我收到一个流时,我最终使用decode()函数使其正常工作。

retval = sock.recv(1024).decode()

解码非常有用。不确定它是否适用于您的情况,但请试一试。