Convert an int value to unicode
我正在使用pyserial,需要发送一些小于255的值。如果我发送int本身,则会发送int的ascii值。所以现在我把int转换成一个unicode值,并通过串行端口发送它。
1 2 3 4
| 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的最佳方法是什么?
- python2还是python3?(猜对python2,但有很大区别)你确定unichr是呼叫崩溃吗?您如何实际发送联合国人力资源部返回的数据?
- python 3中不存在unichr(),所以这是python 2。在python 3(转换为unicode字符)中,unichr()被命名为chr()。
在python 2中-首先将其转换为字符串,然后转换为unicode。
1
| str(integer).decode("utf-8") |
我认为最好的方式。与任何整数一起使用,如果将字符串作为输入,则加号仍然有效。
由于注释更新了编辑:对于python 2和3——这两种方法都适用,但有点混乱:
1
| str(integer).encode("utf-8").decode("utf-8") |
- 虽然很难看,但str(integer).encode("utf-8").decode("utf-8")将在python 2和3上工作,而上面的仅在python2上工作。
只要一个int小于256,就用chr(somenumber)得到它的1字节值。然后,Pyserial会很好地发送它。
如果您想通过pyserial发送东西,那么最好查看标准库中的struct模块,它可以处理endian问题、打包问题以及您可能需要的每种数据类型(1字节或以上)的编码。
- 很有效,谢谢
- @用户2578666:如果一个回复对您有用,并且您将其标记为"已接受",那么对它进行投票也是公平的。欢迎使用StackOverflow!
- 还没有代表。必须赢得它:-)
- @用户2578666:我明白了——我不记得这条规则。愿你的声誉迅速增长。:)
- CHR(32)正在返回""空格,其他数字工作正常。如何克服价值32?
- chr(32)也是0x20,它是空格字符——您希望看到什么?
使用chr()函数;您发送的值小于256但大于128,但正在创建Unicode字符。
然后,必须首先对Unicode字符进行编码,才能获得字节字符,并且编码失败,因为您使用的值超出了ASCII范围(0-127):
1 2 3 4
| >>> 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(),则创建一个一个字符的字节字符串,而不必进行隐式编码:
1 2
| >>> str(chr(169))
'\xa9' |
您可能希望研究的另一种方法是struct模块,特别是当您需要发送大于255的整数值时:
1 2
| >>> struct.pack('!H', 1000)
'\x03\xe8' |
例如,上面的示例将一个整数按网络字节顺序打包成无符号短字符串。
- 我猜你的意思是"字节",而不是"字节字符"?"字节字符"不是一个常见的表达式,它几乎是一种矛盾修饰语。此外,默认编码不必是ASCII:它正式名称为sys.getdefaultencoding()。
- @eol:这是python 2,这是一个字符串对象,实际上是一个字节序列。但是循环它会给您长度为1的字符串;字节字符。
- @EOL:当涉及到隐式编码(连接字符串和Unicode,比较是否相等等)时,python 2上的默认编码是ascii。
- @eol:不要将其与sys.stdout编解码器的print语句/函数编码混淆。
- 你有没有说明这一点的推荐信?我一直在找它。
- @eol:参见unicode howto:如果不使用encoding参数,则使用ASCII编码进行转换。
- 您给出的引用是关于unicode()函数的,而不是默认情况下Unicode字符串的编码方式。你说的是ASCII,我知道使用的编码是sys.getdefaultencoding()。我可能误解了文档,但我还是找不到更明确的内容。
- @EOL:但是您可以在Python提示符中亲自尝试我的示例。sys.getdefaultencoding()是用于编码print输出的编解码器。Unicode和字符串之间的隐式转换使用'ASCII'。
- 关于这两点,我愿意相信你。:)但这是否在文档中?
- 我过会儿会给你找一份推荐信的。但同样的规则适用于所有没有显式编解码器的字符串转换;Unicode到字节字符串,反之亦然。
- 实际上我尝试过:python 2通常不使用ascii连接字符串和unicode字符串。您可以尝试使用和不使用sys.setdefaultencoding('UTF8')的u"" +"é":如果使用utf-8,它会起作用,并且显示连接确实使用sys.getdefaultencoding()。它还用于使用None编码(标准输出在python 2中重定向到文件时发生)打印到sys.stdout。
- 如果设置了不同的编码,则替换了默认编码。请注意,由于某种原因,sys.setdefaultencoding()从sys中删除,需要重新加载sys才能访问。
- 事实上(这是我给出的链接)。我明白我的困惑来自何处:对于"默认编码是ASCII",您的意思是sys.getdefaultencoding()默认为ASCII,而我理解str()转换使用的是ASCII。对不起,对不起。
- 让我们在聊天中继续讨论
我认为最好的解决方案是明确地说,您希望将数字表示为字节(而不是字符):
1 2 3
| >>> import struct
>>> struct.pack('B', 128)
>>> '\x80' |
这使得您的代码在python 2和python 3中都可以工作(在python 3中,结果应该是一个bytes对象)。在python 3中,另一种选择是使用新的bytes([128])创建值为128的单字节。
我不太喜欢chr()解决方案:在python中,它们生成(字符,而不是字节)字符串,在将其发送到任何地方之前需要对其进行编码(文件、套接字、终端等)。python中的chr()相当于问题的python(2)unichr()。struct解决方案的优点是,无论Python的版本是什么,都能正确地生成一个字节。如果您想使用chr()通过串行端口发送数据,则需要控制随后必须进行的编码。当python使用的默认编码是utf-8(我认为是这种情况)时,代码可能会工作,但这是因为小于256的代码点的Unicode字符可以用utf-8编码为单个字节。这增加了一个我不推荐的不必要的微妙和复杂的层(它使代码更难理解,如果必要的话,调试)。
因此,我强烈建议您使用上面的方法(Steve Barnes和Martijn Pieters也曾暗示过):它清楚地表明您想要生成一个字节(而不是字符)。即使您使用python 3运行代码,它也不会给您带来任何惊喜,而且它使您的意图更加清晰和明显。
- Bravo@ EOL——C++继承的一个(可能是很多的)误导性的事情之一是,在长度为1的字符串、单个字符(即本地编码文本和字节)之间没有任何区别。