使用pybind11开发python扩展库
Posted caimouse
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用pybind11开发python扩展库相关的知识,希望对你有一定的参考价值。
继续前面的文章来学习,已经知道使用这个库来写python扩展库是轻松愉快的事情,但还是有很多细节需要学习的,毕竟C++是一个比较灵活的语言。比如在C++里写一些支持使用缺省参数值的函数,如下:
int add(int i = 1, int j = 2) {
return i + j;
}
从上面参数可见,i缺省的值为1,j缺省的值是2。这个是C++的函数定义,如果要把它改为python调用的扩展,是否直接这样就可以支持的呢?可以说不行的,目前还做不到这样。需要使用额外的语法规则才可以,如下:
m.def("add", &add, "A function which adds two numbers",
py::arg("i") = 1, py::arg("j") = 2);
这里使用了py::arg()函数来实现这个功能。这样在python那边调用,就可以使用缺省参数了,在C++里也不一定要有缺省参数。代码如下:
//
//测试pybind11的简单例子。
//蔡军生 2021-06-21
//
#include <pybind11/pybind11.h>
namespace py = pybind11;
using namespace pybind11::literals;
int add(int i, int j) {
return i + j;
}
PYBIND11_MODULE(TestAdd, m) {
m.doc() = "pybind11 example plugin"; // optional module docstring
m.def("add", &add, "A function which adds two numbers");
//提供关键字参数
m.def("addKey", &add, "A function which adds two numbers",
py::arg("i"), py::arg("j"));
//短名称的方式提供关键字参数
m.def("add2", &add, "i"_a, "j"_a);
//使用默认参数的方式
m.def("add3", &add, "A function which adds two numbers",
py::arg("i") = 1, py::arg("j") = 2);
}
python的调用代码:
#
import TestAdd
print(dir(TestAdd))
print(TestAdd.add(1, 2))
#提供关键字参数
print(TestAdd.addKey(j = 10, i = 20))
print(TestAdd.add2(j = 10, i = 20))
print(TestAdd.add3(j = 10, i = 20))
print(TestAdd.add3())
运行的输出结果:
当然也可以使用简捷的方式:_a的来定义:
// 正常方式
m.def("add1", &add, py::arg("i") = 1, py::arg("j") = 2);
// 快捷方式
m.def("add2", &add, "i"_a=1, "j"_a=2);
这两种效果是一样的。
我们学习python就知道,一个模块里还有属性的功能,在C++里也可以实现这样的功能,这时需要使用库的attr函数来实现,如下:
//属性导出
m.attr("the_answer") = 42;
py::object world = py::cast("World");
m.attr("what") = world;
普通的属性值可以通过赋值来自动转换,比如这里数值42自动转换为整数。而有一些类型就不能这样自动转换了,这时候需要使用py::cast来转换,比如这里字符串world。
在python里测试的代码如下:
print(TestAdd.the_answer)
print(TestAdd.what)
这时运行后输出的结果:
通过上面这样的方式,就可以导出属性的功能。
以上是关于使用pybind11开发python扩展库的主要内容,如果未能解决你的问题,请参考以下文章