Wie kann ich eine Cython-Funktion schreiben, die ein Byte-String-Objekt (eine normale Zeichenfolge, ein Bytearray oder ein anderes Objekt, das dem buffer protocol folgt) als typed memoryview schreibt?Wie Cython typed memoryviews verwendet werden, um Zeichenfolgen von Python zu akzeptieren?
Nach dem Unicode and Passing Strings Cython Tutorial Seite sollten folgende Arbeiten:
cpdef object printbuf(unsigned char[:] buf):
chars = [chr(x) for x in buf]
print repr(''.join(chars))
Es funktioniert für Bytearrays und anderen beschreibbaren Puffer:
$ python -c 'import test; test.printbuf(bytearray("test\0ing"))'
'test\x00ing'
Aber es funktioniert nicht für normale Strings und andere schreibgeschützte Pufferobjekte:
$ python -c 'import test; test.printbuf("test\0ing")'
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "test.pyx", line 1, in test.printbuf (test.c:1417)
File "stringsource", line 614, in View.MemoryView.memoryview_cwrapper (test.c:6795)
File "stringsource", line 321, in View.MemoryView.memoryview.__cinit__ (test.c:3341)
BufferError: Object is not writable.
Looki ng am generierten C-Code übergibt Cython immer das PyBUF_WRITABLE
-Flag an PyObject_GetBuffer()
, die die Ausnahme erklärt.
Ich kann manuell einen Blick in die Puffer-Objekt selbst, aber es ist nicht so bequem:
from cpython.buffer cimport \
PyBUF_SIMPLE, PyBUF_WRITABLE, \
PyObject_CheckBuffer, PyObject_GetBuffer, PyBuffer_Release
cpdef object printbuf(object buf):
if not PyObject_CheckBuffer(buf):
raise TypeError("argument must follow the buffer protocol")
cdef Py_buffer view
PyObject_GetBuffer(buf, &view, PyBUF_SIMPLE)
try:
chars = [chr((<unsigned char *>view.buf)[i])
for i in range(view.len)]
print repr(''.join(chars))
finally:
PyBuffer_Release(&view)
$ python -c 'import test; test.printbuf(bytearray("test\0ing"))'
'test\x00ing'
$ python -c 'import test; test.printbuf("test\0ing")'
'test\x00ing'
Bin ich etwas falsch zu machen, oder hat Cython unterstützen Objekte nicht Nötigung schreibgeschützt Puffer (wie normale Strings) in typisierte memoryview-Objekte?
Ich habe Ihren Patch [hier] gefunden (https://mail.python.org/pipermail/cython-devel/2015-February/004316.html), sogar das Hinzufügen von 'const' hilft nicht, also bedeutet das die vorgeschlagene Dokumentation funktioniert nicht. – dashesy