Python:零拷贝,同时截断字节缓冲区

时间:2014-07-24 09:10:24

标签: python

这是关于Python的noob问题。

Python中是否有一种方法可以从bytearray的开头截断几个字节,并在不将内容复制到另一个内存位置的情况下实现此目的?以下是我正在做的事情:

inbuffer = bytearray()
inbuffer.extend(someincomingbytedata)
x = inbuffer[0:10]
del inbuffer[0:10]

我需要保留截断的字节(由x引用)并对其执行一些操作。

x将指向与inbuffer [0]相同的内存位置,或者上述代码中的第3行是否会复制数据。另外,如果没有复制,最后一行中的删除也会删除x引用的数据吗?由于x仍然引用该数据,因此GC不应该回收它。是吗?

修改

如果这不是截断字节缓冲区并在不复制的情况下返回截断字节的正确方法,是否还有其他类型可以安全地支持此类操作?

2 个答案:

答案 0 :(得分:0)

很容易检查:

>>> inbuffer = bytearray([1, 2, 3, 4, 5])
>>> x = inbuffer[0:2]
>>> print id(x) == id(inbuffer)
False

所以它不是同一个对象。

此外,您要求x指向inbuffer[0]。你似乎误解了一些东西。 Python中的数组与C中的数组的工作方式不同。inbuffer的地址不是inbuffer[0]的地址:

>>> inbuffer = bytearray([1, 2, 3, 4, 5])
>>> print id(inbuffer) == id(inbuffer[0])
False

这些是C级数组的包装器。

同样在Python中,一切都是对象。并且Python缓存最多256个(bytearray的范围)的所有整数。因此,唯一复制的是指针:

>>> inbuffer = bytearray([1, 2, 3, 4, 5])
>>> print id(inbuffer[0]) == id(1)
True

答案 1 :(得分:0)

您可以使用迭代器协议和itertools.islicesomeincomingbytedata迭代中提取前10个值,然后将其余值放入inbuffer。对于所有字节,这并没有使用相同的内存,但是它与使用bytearray避免不必要的复制一样好:

import itertools

it = iter(someincomingbytedata)
x = bytearray(itertools.islice(it, 10)) # consume the first 10 bytes
inbuffer = bytearray(it)                # consume the rest

如果您确实需要事先进行阅读,然后在不复制的情况下有效地查看其中的各个切片,您可以考虑使用numpy。如果将数据加载到numpy数组中,稍后获取的任何切片都将显示在同一内存中:

import numpy as np

inbuffer = np.array(someincomingdata, dtype=np.uint8)  # load data into an array of bytes
x = inbuffer[:10]  # grab a view of the first ten bytes, which does not require a copy
inbuffer = inbuffer[10:]  # change inbuffer to reference a slice; no copying here either