为什么不能从数组对象中获取Py_buffer?

时间:2011-02-02 17:43:50

标签: python arrays buffer memoryview pep3118

python documentation on array明确指出数组符合缓冲区接口。它甚至建议不使用buffer_info()方法。但是当我尝试使用PyObject_GetBuffer()从C / C ++代码中获取Py_Buffer或者使用python的memoryview时,我就会失败。

例如,在python中(我使用的是2.7版):

>>> a = array.array('c')
>>> memoryview(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: cannot make memory view because object does not have the buffer interface

实际上,当我搜索python的代码库时,只有bytearrayobject(bytearray),memoryobject(memoryview)和stringobject(str)在它们上面设置了所需的Py_TPFLAGS_HAVE_NEWBUFFER标志。据我了解,文档是错误的; 数组不支持缓冲区接口。

我可以使用支持缓冲区接口的bytearray,问题是我需要数组的实用fromfile()方法来读取我可以在我的C / C ++代码中使用的缓冲区。

是否有替代方案可以让我将文件读入缓冲区并使用C代码中的缓冲区,而不涉及内存副本? (我想处理大二进制文件,复制是不太理想的选择)。

2 个答案:

答案 0 :(得分:4)

memoryview仅适用于支持Python 3缓冲区接口的对象。 Python 3中的array.array可以,但在Python 2.7中却没有。您可能想要为此提交错误报告。只需使用bytearray(或str,如果您以只读方式使用它)。两者都支持memoryview就好了。

答案 1 :(得分:2)

Python 2.6+有两个不同的缓冲接口,就像它有两种不同的类类型:经典版本和Python 3版本。

来自Python/C API Reference Manual

  

支持缓冲区接口的两个对象示例是字符串和数组。字符串对象以缓冲区接口的面向字节的形式公开字符内容。数组只能通过旧式缓冲区接口显示其内容。此限制不适用于Python 3,其中memoryview对象也可以从数组构建。

在Python 2.7代码中,您可以使用buffer函数使用旧式缓冲区,使用memoryview使用新式缓冲区。 Python 3仅支持后者。

Python 2 C API中存在类似的区别; PyObject_GetBuffer用于新缓冲区接口,PyBuffer_FromObject / PyBuffer_FromReadWriteObject用于旧缓冲区接口(并且应该适用于数组)。有关详细信息,请参阅上面的链接。