2011-02-02 11 views
6

Il python documentation on array indica chiaramente che l'array è conforme all'interfaccia del buffer. Suggerisce anche di non usare il metodo buffer_info(). Ma quando cerco di ottenere un Py_Buffer dal codice C/C++ con PyObject_GetBuffer() o di usare python's memoryview, ottengo un errore.Perché non è possibile ottenere un Py_buffer da un oggetto array?

Per esempio, in python (io uso la versione 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 

In realtà, quando cerco base di codice di Python, solo bytearrayobject (ByteArray), memoryobject (memoryview), e stringobject (str) hanno il flag Py_TPFLAGS_HAVE_NEWBUFFER richiesto su di essi. Per quanto ne so, la documentazione è sbagliata; L'array non supporta l'interfaccia del buffer.

Potrei usare bytearray che supporta l'interfaccia buffer, il problema è che ho bisogno del pratico metodo fromfile() dell'array per leggere in un buffer che posso usare nel mio codice C/C++.

Esiste un'alternativa che consenta di leggere un file in un buffer e utilizzare questo buffer dal codice C e non coinvolgere le copie di memoria? (Voglio trattare grandi file binari e copiare è un'opzione meno desiderabile).

risposta

3

memoryview funziona solo su oggetti che supportano l'interfaccia del buffer Python 3. array.array in Python 3 sì, ma non in Python 2.7. Potresti voler presentare una segnalazione per questo. Basta usare l'bytearray (o str se lo si utilizza in sola lettura). Entrambi supportano memoryview bene.

+0

D'accordo, come ho detto nella mia domanda. Ma ... bytearray non ha il pratico metodo fromfile. Immagino di poter usare un oggetto stringa per rappresentare i miei dati binari, ma sapere che un buffer (come bytearray) può essere riempito da file espande le mie opzioni. C'è anche il caso dell'angolo unicode di una stringa che verrebbe eliminato se potessi usare un altro tipo di buffer. – David

+2

Il bug report è qui: http://bugs.python.org/issue17145 – mpb

2

Python 2.6+ ha due diverse interfacce buffer, proprio come ha due diversi tipi di classe: la versione classica e la versione Python 3.

Dal Python/C API Reference Manual:

Due esempi di oggetti che supportano l'interfaccia tampone sono stringhe e array. L'oggetto stringa espone il contenuto del carattere nella forma orientata al byte dell'interfaccia del buffer. Un array può esporre solo i suoi contenuti tramite l'interfaccia buffer vecchio stile. Questa limitazione non si applica a Python 3, dove gli oggetti memoryview possono essere costruiti anche dagli array.

In Python 2.7 del codice, è possibile lavorare con i buffer vecchio stile con la funzione buffer, e buffer di nuovo stile utilizzando memoryview. Python 3 supporta solo quest'ultimo.

Una distinzione simile esiste nell'API Python 2 C; PyObject_GetBuffer è per la nuova interfaccia buffer, PyBuffer_FromObject/PyBuffer_FromReadWriteObject è per la vecchia interfaccia del buffer (e dovrebbe funzionare per gli array). Vedi il link sopra per maggiori informazioni.

Problemi correlati