python array.tostring() 包含 NUL 字节
我在一个单元测试的TestCase里有以下代码(作为示例)
def test(self):
a = array('u','\0'*3)
a[0] = 'h'
a[1] = 'h'
a[2] = 'h'
self.assertEqual(a.tostring(), "hhh")
这个断言失败了,出现了以下错误:
AssertionError: b'h\x00\x00\x00h\x00\x00\x00h\x00\x00\x00' != 'hhh'
现在我明白我创建的数组是用来存储Unicode字符的,每个字符占用4个字节,所以我输入的每个字符后面都有额外的3个NUL字节。我的问题是:
- 我能不能在我的断言里面直接把字符串"hhh"转换成Unicode表示?
- 有没有什么ASCII选项可以用来创建我的数组?
补充说明:为了回答出现的问题:
- 我使用的是Python 3
- 数组是来自array模块,可以用以下方式导入:from array import array
2 个回答
1
你所做的事情是明确请求你的数组以 bytes
的形式表示。显然,这和以 unicode 的形式表示是不一样的。
根据文档:
array.tostring(): 这是一个不推荐使用的旧名称,实际上是 tobytes() 的别名。
array.tobytes(): 这个方法会把数组转换成机器能理解的值,并返回字节表示(这和用 tofile() 方法写入文件时的字节序列是一样的)。
在 3.2 版本中:为了更清楚,tostring() 被改名为 tobytes()。
你需要使用 tounicode
方法:
>>> import array
>>> s = "a\xbb\ucccc\U0001dddd"
>>> array.array('u', s).tounicode() == s
True
如果你是在把一些代码从 Python 2.x 迁移过来,你会发现这和你在那里的写法是相对应的;唯一的不同是 Python 2.x 版本的代码片段会是 s = u"等等等等"
。
类型 'u' 是数组模块中一个很少有人去的地方,而这个模块本身也是 Python 中一个不太常见的部分。如果你不是在从 Python 2.x 迁移过来,你可能想说一下你想实现什么(比如可变字符串?),这样可以得到一些指导。
3
我猜你是在用Python3,这个版本似乎没有'c'
这个选项可以用在array
上。
在这种情况下,我会这样做:
a = array.array("b",4*(0,))
a[0] = 'h'
a[1] = 'h'
a[2] = 'h'
另外一个选择是:
a=array.array('u', "hhh") # the same as yours, but shorter
a.tounicode()
但这样你得到的是一个Unicode字符串,而不是bytes()
对象。