广告
返回顶部
首页 > 资讯 > 后端开发 > Python >跟我一起学习pybind11 之一
  • 144
分享到

跟我一起学习pybind11 之一

跟我一起 2023-01-31 08:01:09 144人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

pybind11是一个轻量级的“Header-only”的库,它将c++的类型暴露给python,反之亦然。主要用于将已经存在的C++代码绑定到Python。pybind11的目标和语法都类似于boost.python库。利用编译时的内

pybind11是一个轻量级的“Header-only”的库,它将c++的类型暴露给python,反之亦然。主要用于将已经存在的C++代码绑定到Python。pybind11的目标和语法都类似于boost.python库。利用编译时的内省来推断类型信息。

boost.python最大问题在于,boost太过复杂和庞大。pybind11除去注释,代码仅仅4000多行,需要依赖Python2.7或python3

支持的编译器

  1. Clang/LLVM (any non-ancient version with C++11 support)
  2. GCC 4.8 or newer
  3. Microsoft Visual Studio 2015 or newer
  4. Intel C++ compiler v17 or newer

介绍pybind11的基本特性。

编译测试用例

linux/MacOS

需要安装python-dev或者python3-dev、cmake。

mkdir build
cd build
cmake ..
make check -j 4

最后一行命令make check -j 4将会编译并自动执行测试用例。

windows

仅仅支持Visual Studio 2015以及更新的版本。

mkdir build
cd build
cmake ..
cmake --build . --config Release --target check

以上命令将会创建一个Visual Studio工程,并且该工程将会被自动编译。

注意:如果所有的测试都失败了,请确保Python二进制类型和测试用例被编译的二进制类型与处理器类型匹配。

头文件和命名空间

为了简洁起见,所有的示例都将假设存在以下两行代码:

#include <pybind11/pybind11.h>
namespace py = pybind11;

某些功能也许需要其它更多的头文件,但是那些部分将在需要时列出来。

绑定简单函数

让我们以一个极度简单的函数来开始创建python绑定,函数完成两数相加并返回结果

int add(int i, int j)
{
    return i + j;
}

为简单起见,我们将函数和绑定代码都放在example.cpp这个文件中

#include <pybind11/pybind11.h>
namespace py = pybind11;

int add(int i, int j)
{
    return i + j;
}

PYBIND11_MODULE(example, m)
{
    m.doc() = "pybind11 example plugin"; // 可选的模块说明

    m.def("add", &add, "A function which adds two numbers");
}

PYBIND11_MODULE()宏函数将会创建一个函数,在由Python发起import语句时该函数将会被调用。模块名字“example”,由宏的第一个参数指定(千万不能出现引号)。第二个参数"m",定义了一个py::module的变量。函数py::module::def()生成绑定代码,将add()函数暴露给Python。


注意:仅仅只需要少量的代码就能完成C++到Python的绑定工作,所有关于函数参数、返回值的细节,将会被模板元编程自动推导出来!这种整体的方法和语法都借鉴了Boost.Python,但是其底层实现是完全不同的。


pybind11是一个“header-only”的库,因此不需要链接(依赖)任何库,也没不需要任何的转换步骤。例如在Linux中,这个例子可以直接使用以下命令来编译:

c++ -O3 -Wall -shared -std=c++11 -fPIC `python3 -m pybind11 --includes` example.cpp -o example `python3-config --extension-suffix`

对于完整的跨平台的指令,详情请参考“构建系统(build systems)”章节

该例子被构建完成之后,将会生成一个可以被导入(import)到Python的二进制模块。被编译的模块位于当前目录,下面将展示如何在Python回话中使用刚刚生成的模块:

import example
example.add(1, 2)

关键字参数

(针对前一个例子)做一个简单修改,它将使得告知Python关于参数的名字成为可能(在本例中就是“i"和”j“)

m.def("add", &add, "A function which adds two numbers", py::arg("i"), py::arg("j"));

py::arg是众多特殊标签之一,它们能将元数据(metadata)传递给py::module::def()。通过这个简单的修改,我们可以利用“keyWord arguments”来调用函数了。这在多参数的场景下,是一个更具可读性的方案。下面将展示如何在Python中使用“keyword arguments”:

import example
# 参数的名字也将出现在文档的函数签名中。
help(example)
example.add(i=1, j=2)

还可以用较短的命名参数表示法:

    using namespace pybind11::literals;
    m.def("add2", &add, "i"_a, "j"_a);

_a后缀是一个C++11的字面字,与py::arg是等价的。

默认参数

现在假设函数具有默认参数:

int add(int i = 1, int j = 2)
{
    return i + j;
}

不幸的是,pybind11不能自动地提取这些参数,因为他们(默认参数)不是函数的类型信息。不过可以利用py::arg扩展来很很简单的实现这些特性。下面例子将展示pybind11对默认参数的支持:

PYBIND11_MODULE(example, m)
{
    m.doc() = "pybind11 example plugin"; // 可选的模块说明
    // default argument
    m.def("add3", &add, "A function which adds two numbers", py::arg("i") = 1, py::arg("j") = 2);
}

现在在python中使用带默认参数的add函数:

>>> import example
>>> help(example.add3)
Help on built-in function add3 in module example:

add3(...) method of builtins.PyCapsule instance
    add3(i: int = 1, j: int = 2) -> int

    A function which adds two numbers

>>> example.add3()
3
>>> example.add3(3)
5
>>> example.add3(j=3)
4
>>>

导出变量

在pybind11通过py::module::attr() 函数实现从C++中导出变量到Python中。内建的类型和泛型对象在被指定为属性(attribute)时将会被自动的转换,同事也可以使用函数py::module::cast进行显示的转换。

PYBIND11_MODULE(example, m)
{
    m.attr("the_answer") = 42;
    py::object world = py::cast("World");
    m.attr("what") = world;
}

下面的示例将展示如何在Python中访问导出的变量:

>>> import example
>>> example.the_answer
42
>>> example.what
'World'
>>>
>>> example.the_answer = 100
>>> example.the_answer
100
>>>

支持数据类型

大量可以开箱即用的数据类型,可以无缝地用作函数参数、返回值或者被py::cast用来转换。这部分内容将在类型转换章节(Type conversions)进行介绍。


--结束END--

本文标题: 跟我一起学习pybind11 之一

本文链接: https://www.lsjlt.com/news/193163.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 跟我一起学习pybind11 之一
    pybind11是一个轻量级的“Header-only”的库,它将C++的类型暴露给Python,反之亦然。主要用于将已经存在的C++代码绑定到Python。pybind11的目标和语法都类似于boost.python库。利用编译时的内...
    99+
    2023-01-31
    跟我一起
  • 跟我一起学写Makefile-Lesso
    [url]http://www.chinaunix.net[/url]...
    99+
    2023-01-31
    跟我一起 Makefile Lesso
  • 我的Node.js学习之路(一)
    一,node.js介绍 这些网上一大堆信息,我只精简 1,什么是node.js 从核心上说:Node.js是个事件驱动的服务器端javascript环境,也就是说,我们可以像使用PHP,Ruby和P...
    99+
    2022-06-04
    之路 Node js
  • 让我们一起来学习一下什么是javascript的闭包
    目录一、常见的闭包二、实例详解总结什么是闭包: 闭包是一个存在内部函数的引用关系。 该引用指向的是外部函数的局部变量对象(前提是内部函数使用了外部函数的局部变量) 闭包的作用: 延长...
    99+
    2022-11-13
  • 【我们一起自学Python】-转载:py
    看到一篇很好的python读写excel方式的对比文章: 用Python读写Excel文件关于其他版本的excel,可以通过他提供的链接教程进行学习。XlsxWriter:https://github.com/jmcnamara/XlsxW...
    99+
    2023-01-31
    我们一起 Python py
  • 我的NodeJs学习小结(一)
    这第一篇就谈谈NodeJs的一些编程细节吧。 1、遍历数组 for (var i=0, l=arr.length; i<l; i++) 这样写的一个好处就是让每次循环少一步获取数...
    99+
    2022-06-04
    小结 NodeJs
  • 学习之Redis(一)
    一、redis简介   一般学习,最好先去官网,之所以建议看官网,是因为这是一手的学习资料,其他资料都最多只能算二手,一手资料意味着最权威,准确性最高。https://redis.io/topics/introduction。如果像我一样,...
    99+
    2018-05-31
    学习之Redis(一)
  • 我的python学习--第十一天
    上午:作业讲解bootstrap-multiselect插件sweetalert插件下午:datatables----表格插件datetimepicker----时间插件Validform----表单验证插件锁定用户禁止登录---...
    99+
    2023-01-31
    第十一天 python
  • Python中的集合一起来学习一下
    目录一、什么是集合二、集合的创建方式三、集合的相关操作3.1集合元素的判断操作3.2集合元素的新增操作3.3集合元素的删除操作四、集合之间的关系五、集合的数学操作六、集合生成式总结一...
    99+
    2022-11-13
  • 一起来学习一下JavaScript的事件流
    目录1. 什么是事件流?2. 事件流模型2.1)事件冒泡2.2)事件捕获3. DOM事件流总结1. 什么是事件流 ? 在学习事件流之前我们先看...
    99+
    2022-11-13
  • 一起来学习TypeScript的类型
    目录前言一、类型声明 二、类型1.number2.string3.boolean 4.字面量 5.联合类型 6.any 7.unkn...
    99+
    2022-11-13
  • 一起来学习Python的列表
    目录列表更多的方法列表的嵌套总结列表更多的方法 index():返回指定数据所在位置的下标 (注意:如果查找的数据不存在则报错。)。count():统计指定数据在当前列表中出现的次数...
    99+
    2022-11-13
  • Oracle Hint 学习之一
    APPEDND hint :用于控制insert 语句是否能以直接路径插入的方式插入数据。CACHE hint:用于控制目标sql在执行时是否将全表扫描目标表的数据块放到buffer cache的LRU链表...
    99+
    2022-10-18
  • 一起来学习一下python的数据类型
    目录内置数据类型获取数据类型【type()】str:转换为str(字符串)类型int:转换为int类型float:转换为float类型complex:转换为complex(复数)类型...
    99+
    2022-11-13
  • 一起来学习一下python的数字类型
    目录int数字int类型Float类型complex类型int(),float(),complex()类型之间的转换总结int 数字 python 有3种数字类型int: 整数类型f...
    99+
    2022-11-13
  • 我的python学习--第十四天(一)
    一、运维管理系统(基于Flask)回顾1、权限控制  通过session实现权限控制,session是一个全局字典,当用户登录时,可以获取到用户的用户名,通过查找数据库获取用户的权限保存进session中,在每次页面跳转时同过查询sessi...
    99+
    2023-01-31
    第十四天 python
  • 一起来学习JAVA的运算符
    目录一、赋值运算符二、复合赋值运算符三、算数运算符四、关系运算符五、自运算符六、逻辑运算符七、条件运算符(三元运算符)总结运算符优先级表: 一、赋值运算符 运算符:【=】 含义:把...
    99+
    2022-11-13
  • 一起来学习JavaScript的BOM操作
    目录window对象全局作用域常见事件调节窗口大小定时器setTimeoutthis指向问题location对象转跳页面location常见方法总结window对象 BOM的核心对象...
    99+
    2022-11-13
  • 一起来学习JavaIO的转化流
    目录Java IO 转化流乱码引起转换流读取乱码转换流介绍InputStreamReaderOutputStreamWriter总结Java IO 转化流 乱码引起转换流 读取乱码 ...
    99+
    2022-11-13
  • 一起来学习Vue的组件化
    目录背景定义分类优势首屏加载优化组件之间的关系总体上可以分为两大类:常见使用场景可以分为三类:总结说起组件化,我毕设写的就是和组件化相关的。 当时还拿了优,运气! 话不多说,直接...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作