Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Cython类型的MemoryView从Python接受字符串?_Python_Python 2.7_Cython_Python C Extension_Memoryview - Fatal编程技术网

如何使用Cython类型的MemoryView从Python接受字符串?

如何使用Cython类型的MemoryView从Python接受字符串?,python,python-2.7,cython,python-c-extension,memoryview,Python,Python 2.7,Cython,Python C Extension,Memoryview,如何编写以字节字符串对象(普通字符串、bytearray或后面的另一个对象)为对象的Cython函数 根据Cython教程页面,以下内容应适用: cpdef object printbuf(unsigned char[:] buf): chars = [chr(x) for x in buf] print repr(''.join(chars)) 它适用于字节数组和其他可写缓冲区: $python-c'导入测试;test.printbuf(bytearray(“test\0in

如何编写以字节字符串对象(普通字符串、bytearray或后面的另一个对象)为对象的Cython函数

根据Cython教程页面,以下内容应适用:

cpdef object printbuf(unsigned char[:] buf):
    chars = [chr(x) for x in buf]
    print repr(''.join(chars))
它适用于字节数组和其他可写缓冲区:

$python-c'导入测试;test.printbuf(bytearray(“test\0ing”))
“测试\x00ing”
但它不适用于普通字符串和其他只读缓冲区对象:

$python-c'导入测试;test.printbuf(“test\0ing”)'
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
test.printbuf(test.c:1417)中第1行的文件“test.pyx”
文件“stringsource”,第614行,在View.MemoryView.MemoryView_cwrapper(test.c:6795)中
文件“stringsource”,第321行,在View.MemoryView.MemoryView.\uuu cinit\uuu(test.c:3341)中
BufferError:对象不可写。
查看生成的C代码,Cython总是将
PyBUF\u writeable
标志传递给
PyObject\u GetBuffer()
,这解释了异常

我可以自己手动将视图放入缓冲区对象,但这并不方便:

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)

是我做错了什么,还是Cython不支持将只读缓冲区对象(如普通字符串)强制转换为类型化的memoryview对象?

尽管文档中另有建议,Cython(至少在版本0.22之前)不支持将只读缓冲区对象强制转换为类型化的memoryview对象。Cython总是将
PyBUF_writeable
标志传递给
PyObject\u GetBuffer()
,即使它不需要写访问。这会导致只读缓冲区对象引发异常


我,甚至包括一个(非常粗糙的)补丁。我一直没有得到回复,所以我认为Cython开发人员对修复这个bug不感兴趣。

这个问题在Cython 0.28中得到了解决,发布于2018-03-13()。报告说:

const修饰符可以应用于memoryview声明,以允许只读缓冲区作为输入

还有一个新的问题

如果您这样编写函数,您给出的示例将在Cython 0.28中运行:

cpdef object printbuf(const unsigned char[:] buf):
    chars = [chr(x) for x in buf]
    print repr(''.join(chars))

我发现你的补丁甚至添加
const
都没有帮助,因此这意味着建议的文档不起作用。
const
现在对我来说适用于Cython 0.28.4我也遇到了同样的问题,为什么他们对修复这个问题不感兴趣?你可以尝试以GitHub pull请求的形式提交补丁;并且添加了一些测试用例。事实上,您是否尝试通过GitHub推动该补丁?