前面讲了很多C在Cython中的用法,许多小伙伴可能更喜欢用C++,毕竟C++的STL中很多类型与python类型更加接近(比如:c++的vector与python的list可以很好的转换),因此今天对Cyhon中c++的使用进行简单的介绍。
1 导入C++模块
这里推荐大家使用Jupyter notebook,当然你直接用编辑器也是可以的,按照教程一中的方法进行编译就好了。
- 加载Cython的魔术命令:
%load_ext Cython
- 开启Cython代码块的魔术命令:
%%cython --cplus
(如果是mac,还需要指定一下编译器:%%cython --cplus --compile-args=-stdlib=libc++ --link-args=-stdlib=libc++
)
%load_ext Cython
%%cython --cplus
#注意这里新开一个代码块
from libcpp.string cimport string
cdef string s
s = '欢迎来到Cython的世界'.encode('utf-8')
print(s.decode('utf-8'))
2 C++类型的使用
上述案例中我们使用了c++的string,下面我们列举了一些python常用类型和c++类型的对应关系:
python | c++ |
---|---|
bytes | std::string |
tuple | std::pair |
set | std::set |
list | std::vector 或者 std::list |
dict | std::unordered_map |
注意:
(1)c++中的数字类型是有范围的,而python没有范围,所以这一点上要格外注意哦。在直接赋值的时候,如果用一个超范围的python数赋值给c++ int,编译会报错OverflowError: Python int too large to convert to C long
,但是如果赋值没有超限,而运算中产生了溢出,c++是不会报错的,而是会默认保留剩余的位,所以当你发现你运算中的正整数变成负数了,那么,可能发生了溢出,这时候应该选择long或者long long。
(2)C++的string对应的是字节类型,只能支持ASCII码,所以为了能够显示汉语,需要使用encode()
函数进行转译,然后再用.decode()
在打印的时候翻译出来。
- 案例:list
%%cython --cplus
# list
from libcpp.vector cimport vector
# 创建一个list对象
list_python = [i for i in range(10)]
cdef vector[int] vec_cpp = list_python
# 输出看看
for i in vec_cpp:
print(i)
vec_cpp.push_back(11) # 添加元素,类似于append
print(vec_cpp)
- 案例:字典
%%cython --cplus
# 注:dereference是接引用, preincrement 是c++容器指针的自增
from cython.operator cimport dereference as deref, preincrement as inc
from libcpp.unordered_map cimport unordered_map
# 通过Python对象初始化
cdef unordered_map[int, float] mymap = {i: i/10 for i in range(10)}
# 遍历
cdef:
unordered_map[int, float].iterator it = mymap.begin()
unordered_map[int, float].iterator end = mymap.end()
print("开始遍历...")
while it != end:
# 访问
print("\tKey is %d, Value is %.1f" % (deref(it).first, deref(it).second))
inc(it)
还有很多其他类型,有时间我再往上加。
网友评论