【发布时间】:2019-06-29 14:52:37
【问题描述】:
我正在 Cython 中实现一个函数,该函数需要在某些时候从 C++ std::string 中删除一些 char。为此,我会使用std::string::erase()。但是,当我尝试使用它时,Cython 会强制对象为bytes() 而不是std::string(),此时它找不到.erase()。
为了说明这个问题,这里是一个最小的例子(使用 IPython + Cython 魔法):
%load_ext Cython
%%cython --cplus -c-O3 -c-march=native -a
from libcpp.string cimport string
cdef string my_func(string s):
cdef char c = b'\0'
cdef size_t s_size = s.length()
cdef size_t i = 0
while i + 1 <= s_size:
if s[i] == c:
s.erase(i, 1)
i += 1
return s
def cy_func(string b):
return my_func(b)
这可以编译,但它表示.remove() 行上的 Python 交互,以及当我尝试使用它时,例如
b = b'ciao\0pippo\0'
print(b)
cy_func(b)
我明白了:
AttributeError Traceback(最近一次调用最后一次) AttributeError: 'bytes' 对象没有属性 'erase'
在“_cython_magic_5beaeb4004c3afc6d85b9b158c654cb6.my_func”中忽略了异常 AttributeError: 'bytes' 对象没有属性 'erase'
我该如何解决这个问题?
注意事项
- 如果我将
s.erase(i, 1)替换为s[i] == 10,我会得到my_func(),而无需与Python 交互(甚至可以使用nogil指令)。 - 我知道我可以在 Python 中使用
.replace(b'\0', b'')进行此操作,但它是我希望使用 Cython 优化的更长算法的一部分。
【问题讨论】:
-
尝试使用 string.replace 而不是 string.erase