【发布时间】:2017-03-21 05:12:13
【问题描述】:
我正在查看第 3 方 API,他们有以下代码:
def array_u16 (n): return array('H', '\0\0'*n)
我知道'\0' 表示NULL,'\0\0' 有什么特殊含义还是仅表示 2 NULLs?
【问题讨论】:
标签: python string python-2.7 python-3.x
我正在查看第 3 方 API,他们有以下代码:
def array_u16 (n): return array('H', '\0\0'*n)
我知道'\0' 表示NULL,'\0\0' 有什么特殊含义还是仅表示 2 NULLs?
【问题讨论】:
标签: python string python-2.7 python-3.x
array 类接受一个格式字符(称为类型码),后跟一个初始值设定项。 H 表示无符号短,最小大小为 2 个字节,所以 '\0\0' 满足这一点。 * n部分是将整个数组初始化为NULL字节。
【讨论】:
它只是确保提供两个字节n 次,因此数组的大小将等于n。如果提供了'\0',则结果数组将具有size == n//2 (due to the type-code 'H' requiring 2 bytes);这显然是违反直觉的:
>>> array('H', '\0' * 10) # 5 elements
array('H', [0, 0, 0, 0, 0])
>>> array('H', '\0\0' * 10) # 10 elements
array('H', [0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
请注意,在 Python 3 中,如果您需要相同 sn-p 来工作,您必须 provide a bytes object 作为initializer 的initializer 参数@:
>>> array('H', b'\0\0' * 10)
array('H', [0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
由于您也无法在 Python 2 中提供 u'' 字符串。除此之外,行为保持完全相同。
所以'\0\0' 是为了方便起见,仅此而已。 '\0\0' 没有附加任何语义。
'\0' 也没有真正附加任何语义(例如,C)'\0' 只是 Python 中的另一个字符串。
作为此行为的另一个示例,对于具有最少 2 字节的无符号整数,使用类型代码为 'I' 的数组进行初始化,但在 Python 的 64bit 构建中使用 4。
本着您提供的 sn-p 的精神,您可以通过执行以下操作来初始化数组:
>>> array('I', b'\0\0\0\0' * 10)
array('I', [0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
是的,四倍于b'\0' 字符串以获取10 元素。
作为 final 说明 -- 以下时序是在 Python 3 上执行的,但 2 是相同的 -- 你可能想知道他为什么使用 '\0\0\' * n 而不是更直观的[0] * n 来初始化数组。嗯,它的速度相当快:
n = 10000
%timeit array('I', [0]*n)
1000 loops, best of 3: 212 µs per loop
%timeit array('I', b'\0\0\0\0'* n)
100000 loops, best of 3: 6.36 µs per loop
当然,您可以通过将bytearray 提供给array 来做得更好(对于'b' 以外的类型代码)。用空字节初始化a bytearray is by providing an int as the number of items to initialize 的一种方法:
%timeit array('I', bytearray(n))
1000000 loops, best of 3: 1.72 µs per loop
但是,如果我没记错的话,bytearray(int) 初始化字节数组的方式可能会在 3.7+ 中被弃用:-)。
【讨论】:
看起来这个函数返回一个由 16 位组成的数组;因此\0\0 可能代表创建两个字节(16 位)的数据。换句话说,它返回两个字节的 n 个字。
【讨论】: