将int值转换为unicode

时间:2013-07-13 07:00:16

标签: python character-encoding ascii pyserial

我正在使用pyserial并且需要发送一些小于255的值。如果我发送int本身,则发送int的ascii值。所以现在我将int转换为unicode值并通过串口发送。

unichr(numlessthan255);

However it throws this error:
'ascii' codec can't encode character u'\x9a' in position 24: ordinal not in range(128)

将int转换为unicode的最佳方法是什么?

4 个答案:

答案 0 :(得分:29)

在Python 2中 - 首先将其转换为字符串,然后转换为unicode。

str(integer).decode("utf-8")

我认为最好的方式。适用于任何整数,如果您输入一个字符串作为输入,则仍然有效。

由于评论而更新了编辑:对于Python 2和3 - 这适用于两者但有点混乱:

str(integer).encode("utf-8").decode("utf-8") 

答案 1 :(得分:14)

只要使用chr(somenumber)获取int的1字节值,只要它小于256. pySerial将发送它。

如果您正在通过pySerial发送内容,那么查看标准库中的结构模块是一个非常的好主意,它会处理endian问题,包装问题以及几乎所有的编码您可能需要的数据类型为1个字节或更长。

答案 2 :(得分:10)

使用chr() function代替;您发送的值小于256但大于128,但正在创建Unicode字符。

然后必须首先编码unicode字符以获取字节字符,并且该编码失败,因为您使用的值超出了ASCII范围(0-127):

>>> str(unichr(169))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xa9' in position 0: ordinal not in range(128)

这是正常的Python 2行为;尝试将unicode字符串转换为字节字符串时,必须进行隐式编码,默认编码为ASCII。

如果您改为使用chr(),则创建一个字符的字符串,并且的隐式编码必须发生:

>>> str(chr(169))
'\xa9'

您可能想要研究的另一种方法是struct module,特别是如果您需要发送大于的整数值而不是255:

>>> struct.pack('!H', 1000)
'\x03\xe8'

上面的示例将整数打包为网络字节顺序中的无符号短整数,例如。

答案 3 :(得分:10)

我认为最好的解决方案是明确表示你想将一个数字表示为一个字节(和not as a character):

>>> import struct
>>> struct.pack('B', 128)
>>> '\x80'

这使得您的代码在Python 2和Python 3中都能工作(在Python 3中,结果是,bytes对象)。在Python 3中,另一种方法是使用新的bytes([128])来创建值为128的单个字节。

我不是chr()解决方案的忠实粉丝:in Python 3,他们会产生一个(字符,而不是字节)字符串,需要encoded在将它发送到任何地方之前(文件,套接字,终端......) - Python 3中的chr()等同于问题的有问题的Python 2 unichr()。无论Python版本如何,struct解决方案都具有正确生成字节的优势。如果要通过串行端口使用chr()发送数据,则需要控制必须随后进行的编码。当Python 3使用的默认编码是UTF-8(我认为是这种情况)时,代码可能会起作用,但这是因为代码点小于256的Unicode字符可以编码为UTF中的单个字节-8。这增加了我不推荐的不必要的微妙和复杂的层次(它使代码更难理解,并且如果必要的话,调试)。

所以,我强烈建议你使用上面的方法(Steve Barnes和Martijn Pieters也暗示过):它清楚地表明你想要产生一个字节(而不是字符) )。即使您使用Python 3运行代码也不会给您带来任何惊喜,它会使您的意图更清晰,更明显。