【问题标题】:Why is it not possible to get a Py_buffer from an array object?为什么无法从数组对象中获取 Py_buffer?
【发布时间】:2011-02-02 17:43:50
【问题描述】:

python documentation on array 明确指出 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 标志。据我了解,文档是错误的; 数组不支持缓冲区接口。

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

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

【问题讨论】:

    标签: python arrays buffer memoryview pep3118


    【解决方案1】:

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

    【讨论】:

    • 同意,正如我在问题中所说的那样。但是... bytearray 没有方便的 fromfile 方法。我想我可以使用字符串对象来表示我的二进制数据,但是知道可以从文件中填充缓冲区(如字节数组)扩展了我的选择。如果我可以使用另一种缓冲区类型,也可以消除字符串的 unicode 极端情况。
    【解决方案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 用于旧的缓冲区接口(应该适用于数组)。有关详细信息,请参阅上面的链接。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-03
      • 2021-12-20
      • 1970-01-01
      相关资源
      最近更新 更多