Cython系列教程:四.在Cython中使用c++

前面讲了很多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)

还有很多其他类型,有时间我再往上加。

你可能感兴趣的:(Cython系列教程:四.在Cython中使用c++)