Cython:应何时将字符串定义为char*、str或bytes?
选择适合你场景的Cython字符串类型
让我帮你把这三种字符串类型的区别讲明白,结合你的使用场景给出明确建议:
1. cdef char* mystring = "foo"
这是纯C语言的字节指针,本质是一段原始字节序列(默认是ASCII编码),和Python的Unicode字符串完全不是一个概念。如果你的输入是Python3的Unicode字符串,要转成char*必须先手动编码(比如utf-8),而且后续用作字典键或者Python函数参数时,还得再转回Python对象,不仅麻烦,还很容易出现编码错误。完全不适合你的场景。
2. cdef bytes mystring = "foo"
bytes对应Python的字节串类型,存储的是编码后的字节数据。但你的输入是Unicode字符串,要赋值给bytes变量必须先调用encode()方法指定编码(比如mystring = py_unicode_str.encode('utf-8'))。用作字典键的话,它和原Unicode字符串是完全不同的键(比如"测试"和"测试".encode('utf-8')在字典里是两个独立的键);作为函数参数传给期望Unicode字符串的Python函数时,还得再解码,额外增加了转换成本。不推荐用于你的场景。
3. cdef str mystring = "foo"
这才是最适合你的选择!Cython里的str类型直接对应Python3的Unicode字符串(也就是标准的str对象):
- 可以直接接收来自Python程序的Unicode字符串,不需要任何编码解码转换,从根源上避免乱码问题
- 能直接用作Python字典的键,行为和Python代码里完全一致,不会出现键不匹配的情况
- 作为函数参数传给Python函数或者Cython中期望Python字符串的函数时,无缝衔接,不需要额外处理
总结
结合你的场景(Python3 Unicode字符串、字典键、函数参数),一定要选cdef str类型,它是最贴合Python字符串使用习惯的Cython类型,能帮你省去大量不必要的编码转换工作。
内容的提问来源于stack exchange,提问作者right2clicky
相关产品推荐
相关产品推荐

