2011-02-02 65 views
6

python documentation on array明確指出,陣列符合緩衝區接口。它甚至建議不要使用buffer_info()方法。但是,當我嘗試從PyObject_GetBuffer()從C/C++代碼獲取Py_Buffer或使用python的memoryview時,我得到一個失敗。爲什麼不能從數組對象中獲取Py_buffer?

例如,在蟒蛇(我用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(字節陣列),memoryobject(memoryview)和stringobject(STR)有所需的Py_TPFLAGS_HAVE_NEWBUFFER標誌設置在它們上面。據我瞭解,文件是錯誤的; 數組不支持緩衝區接口。

我可以使用支持緩衝區接口的bytearray,問題是我需要數組的實用fromfile()方法來讀取我可以在我的C/C++代碼中使用的緩衝區。

是否有替代方案可以讓我將文件讀入緩衝區並從C代碼中使用此緩衝區,而不涉及內存副本? (我想處理大的二進制文件和複製是不太理想的選擇)。

回答

3

memoryview僅適用於支持Python 3緩衝區接口的對象。在Python 3中有array.array,但它不在Python 2.7中。您可能想爲此提交一份錯誤報告。只需使用使用bytearray(或str,如果您正在使用它只讀)。兩者都支持memoryview就好了。

+0

同意,正如我在我的問題中所說的。但是... bytearray沒有方便的fromfile方法。我想我可以使用字符串對象來表示我的二進制數據,但知道緩衝區(如bytearray)可以從文件中填充擴展我的選項。如果我可以使用另一種緩衝區類型,還有一個字符串的unicode轉角情況會被消除。 – David 2011-02-02 20:17:49

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用於舊的緩衝區接口(並且應該適用於數組)。請參閱上面的鏈接瞭解更多信息。