使用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扩展库的主要内容,如果未能解决你的问题,请参考以下文章

使用pybind11开发python扩展库

使用pybind11开发python扩展库

使用pybind11来快速开发python程序扩展库

使用pybind11开发python扩展库

使用pybind11开发python扩展库

使用pybind11开发python扩展库