亲宝软件园·资讯

展开

Cython处理C字符串的示例详解

古明地觉 人气:0

楔子

在介绍数据类型的时候我们说过,Python 的数据类型相比 C 来说要更加的通用,但速度却远不及 C。如果你在使用 Cython 加速 Python 时遇到了瓶颈,但还希望更进一步,那么可以考虑将数据的类型替换成 C 的类型,特别是那些频繁出现的数据,比如整数、浮点数、字符串。

由于整数和浮点数默认使用的就是 C 的类型,于是我们可以从字符串入手。

创建 C 字符串

先来回顾一下如何在 Cython 中创建 C 字符串。

cdef char *s1 = b"abc"
print(s1)  # b'abc'

C 的数据和 Python 数据如果想互相转化,那么两者应该存在一个对应关系,像整数和浮点数就不必说了。但 C 的字符串本质上是一个字符数组,所以它和 Python 的 bytes 对象是对应的,我们可以将 b"abc" 直接赋值给 s1。并且在打印的时候,也会转成 Python 的 bytes 对象之后再打印。

或者还可以这么做:

cdef char s1[4]
s1[0], s1[1], s1[2] = 97, 98, 99

cdef bytes s2 = bytes([97, 98, 99])

print(s1)  # b'abc'
print(s2)  # b'abc'

直接声明一个字符数组,然后再给数组的每个元素赋值即可。

Python 的 bytes 对象也是一个字符数组,和 C 一样,数组的每个元素不能超过 255,所以两者存在对应关系。在赋值的时候,会相互转化,其它类型也是同理,举个例子:

# Python 整数和 C 整数是存在对应关系的
# 因为都是整数,所以可以相互赋值
py_num = 123
# 会根据 Python 的整数创建出 C 的整数,然后赋值给 c_num
cdef unsigned int c_num = py_num
# print 是 Python 的函数,它接收的一定是 PyObject *
# 所以在打印 C 的整数时,会转成 Python 的整数再进行打印
print(c_num, py_num)
"""
123 123
"""
# 但如果写成 cdef unsigned int c_num = "你好" 就不行了
# 因为 Python 的字符串和 C 的整数不存在对应关系
# 两者无法相互转化,自然也就无法赋值

# 浮点数也是同理,Python 和 C 的浮点数可以相互转化
cdef double c_pi = 3.14
# 赋值给 Python 变量时,也会转成 Python 的浮点数再赋值
py_pi = 3.14
print(c_pi, py_pi)
"""
3.14 3.14
"""

# Python 的 bytes 对象和 C 的字符串可以相互转化
cdef bytes py_name = bytes("古明地觉", encoding="utf-8")
cdef char *c_name = py_name
print(py_name == c_name)
"""
True
"""

# 注意:如果 Python 字符串所有字符的 ASCII 

加载全部内容

相关教程
猜你喜欢
用户评论