Boost.Python教程:通用技术
下面介绍一些有用的技术,您可以在使用Boost.Python包装代码时使用这些技术。
创建包
Python包是一组模块,为用户提供某种功能。 如果您不熟悉如何创建包, Python教程中提供了对它们的一个很好的介绍。
但是我们使用Boost.Python包装C ++代码。 我们如何为用户提供一个漂亮的包界面? 为了更好地解释一些概念,让我们使用一个例子。
我们有一个有不同含义的C ++库:读取和写入各种格式,对声音数据应用滤波器等。它被命名(方便) sounds
。 我们的库已经有了一个简洁的C ++命名空间层次结构,如下所示:
sounds::core
sounds::io
sounds::filters
我们想向Python用户提供相同的层次结构,允许他编写如下代码:
import sounds.filters
sounds.filters.echo(...) # echo is a C++ function
第一步是编写包装代码。 我们必须使用Boost.Python单独导出每个模块,如下所示:
/* file core.cpp */
BOOST_PYTHON_MODULE(core)
{/* export everything in the sounds::core namespace */...
}/* file io.cpp */
BOOST_PYTHON_MODULE(io)
{/* export everything in the sounds::io namespace */...
}/* file filters.cpp */
BOOST_PYTHON_MODULE(filters)
{/* export everything in the sounds::filters namespace */...
}
编译这些文件将生成以下Python扩展: core.pyd
, io.pyd
和io.pyd
。
注意 | |
---|---|
扩展名 |
sounds/__init__.pycore.pydfilters.pydio.pyd
文件__init__.py
告诉Python该目录sounds/
实际上是一个Python包。 它可以是一个空文件,但也可以执行一些魔术,稍后将会显示。
现在我们的包准备好了。 用户所要做的就是将sounds
放入他的PYTHONPATH并启动解释器:
>>> import sounds.io
>>> import sounds.filters
>>> sound = sounds.io.open('file.mp3')
>>> new_sound = sounds.filters.echo(sound, 1.0)
如果我们想要这种灵活性,我们将不得不使我们的包层次结构复杂化。 首先,我们将不得不更改扩展模块的名称:
/* file core.cpp */
BOOST_PYTHON_MODULE(_core)
{.../* export everything in the sounds::core namespace */
}
请注意,我们在模块名称中添加了下划线。 文件名也必须更改为_core.pyd
,我们对其他扩展模块执行相同的操作。 现在,我们改变我们的包层次结构如下:
sounds/__init__.pycore/__init__.pycore.pydfilters/\_init__.pyfilters.pydio/\_init__.py_io.pyd
请注意,我们为每个扩展模块创建了一个目录,并为每个扩展模块添加了__init__.py。 但是如果我们这样离开,用户将不得不使用以下语法访问核心模块中的函数:
>>> import sounds.core._core
>>> sounds.core._core.foo(...)
from _core import *
我们对其他包也这样做。 现在,用户像以前一样访问扩展模块中的函数和类:
>>> import sounds.filters
>>> sounds.filters.echo(...)
import _filters
def echo_noise(sound):s = _filters.echo(sound)s = _filters.noise(sound)return s
接下来,我们将此行添加到sounds/filters/__init__.py
:
from echo_noise import echo_noise
就是这样。 用户现在可以像filters
包中的任何其他功能一样访问此功能:
>>> import sounds.filters
>>> sounds.filters.echo_noise(...)
在Python中扩展包装对象
由于Python的灵活性,您可以轻松地向类添加新方法,即使它已经创建了:
>>> class C(object): pass
>>>
>>> # a regular function
>>> def C_str(self): return 'A C instance!'
>>>
>>> # now we turn it in a member function
>>> C.__str__ = C_str
>>>
>>> c = C()
>>> print c
A C instance!
>>> C_str(c)
A C instance!
我们可以对使用Boost.Python包装的类执行相同的操作。 假设我们在C ++中有一个类point
:
class point {...};BOOST_PYTHON_MODULE(_geom)
{class_<point>("point")...;
}
如果我们使用上一个会话创建包中的技术 ,我们可以直接编码到geom/__init__.py
:
from _geom import *# a regular function
def point_str(self):return str((self.x, self.y))# now we turn it into a member function
point.__str__ = point_str
从C ++创建的所有点实例也将具有此成员函数! 这种技术有几个优点:
您甚至可以使用元类添加一点语法糖。 让我们创建一个特殊的元类,在其他类中“注入”方法。
# The one Boost.Python uses for all wrapped classes.
# You can use here any class exported by Boost instead of "point"
BoostPythonMetaclass = point.__class__class injector(object):class __metaclass__(BoostPythonMetaclass):def __init__(self, name, bases, dict):for b in bases:if type(b) not in (self, type):for k,v in dict.items():setattr(b,k,v)return type.__init__(self, name, bases, dict)# inject some methods in the point foo
class more_point(injector, point):def __repr__(self):return 'Point(x=%s, y=%s)' % (self.x, self.y)def foo(self):print 'foo!'
>>> print point()
Point(x=10, y=10)
>>> point().foo()
foo!
_point = pointdef point(x=0, y=0):return _point(x, y)
在这个简单的情况下,没有太多的收获,但对于具有许多重载和/或参数的构造函数,这通常是一个很大的简化,同样几乎没有内存占用和关键字支持的零编译时开销。
缩短编译时间
如果您曾经导出过很多类,那么您知道编译Boost.Python包装器需要相当长的时间。 此外,内存消耗很容易变得太高。 如果这导致您出现问题,可以将class_ definitions拆分为多个文件:
/* file point.cpp */
#include <point.h>
#include <boost/python.hpp>void export_point()
{class_<point>("point")...;
}/* file triangle.cpp */
#include <triangle.h>
#include <boost/python.hpp>void export_triangle()
{class_<triangle>("triangle")...;
}
现在,您创建一个main.cpp
文件,其中包含BOOST_PYTHON_MODULE
宏,并调用其中的各种导出函数。
void export_point();
void export_triangle();BOOST_PYTHON_MODULE(_geom)
{export_point();export_triangle();
}
#include <boost/python.hpp>
#include <point.h>
#include <triangle.h>BOOST_PYTHON_MODULE(_geom)
{class_<point>("point")...;class_<triangle>("triangle")...;
}
如果您正在开发C ++库并同时将其导出到Python,也建议使用此方法:类中的更改只需要编译单个cpp,而不是整个包装器代码。
注意 | |
---|---|
如果在编译大型源文件时收到错误消息“致命错误C1204:编译器限制:内部结构溢出” ,此方法也很有用,如FAQ中所述。 |
Boost.Python教程:通用技术相关推荐
- Boost.Python教程:函数
在本章中,我们将更详细地介绍Boost.Python驱动的函数.我们将看到一些工具,可以将C ++函数暴露给Python,避免潜在的pifall,例如悬空指针和引用. 我们还将看到一些工具,使我们更容 ...
- 【通用技术】2个月精通Python爬虫——3大爬虫框架+6场实战+分布式爬虫,包教包会...
网络爬虫(又被称为网页蜘蛛,网络机器人),是一种按照一定的规则,自动的抓取信息的程序或者脚本. 网络爬虫是互联网上进行信息采集的通用手段,在互联网的各个专业方向上都是不可或缺的底层技术支撑.本课程从爬 ...
- python后端教程_Python学习教程(技术干货):关于前后端分离开发入门
原标题:Python学习教程(技术干货):关于前后端分离开发入门 对于程序员来说,其实Tab和空格远远不只是"立场"问题那么简单. 在不同的编辑器里tab的长度可能不一致,所以在一 ...
- python与seo实战课程下载_黑帽seo教程:SEO快排套路与SEO快排Python应用编程技术(零基础)...
黑帽seo教程:SEO快排套路与SEO快排Python应用编程技术(零基础) 授课内容简介 两个模块:「SEO套路」和「SEO应用编程」 「SEO套路」模块,分 "域名.内容&模板. ...
- python文件打包技术免费教程
需求:如何把python文件转化为像电脑软件一样可执行的程序? 技术:这就需要运用到python文件打包技术了.将python文件打包成exe文件,可以在电脑直接运行,也方便向小伙伴分享你的代码执行成 ...
- python教程书籍-大牛推荐的10本学习 Python 的好书
Python:蛇亚目蟒科,主要包括分布于非洲及亚洲的无毒蟒蛇. Python:Richard Clabaugh拍摄的恐怖电影,2000年发行. Python:澳大利亚汽车公司. Python:英国偶发 ...
- Python教程 - Django
Django 系统 环境 Python 3.6 Django 1.8 参考资料 [Django中文教程](https://yiyibooks.cn/xx/django_182/index.html) ...
- python人工智能图像识别_人工智能之Python人脸识别技术,人人都能做识别!
原标题:人工智能之Python人脸识别技术,人人都能做识别! 作者丨Python小哥哥 https://www.jianshu.com/p/dce1498ef0ee 一.环境搭建 1.系统环境 Ubu ...
- 30分钟 Python 教程
Python 教程 本教程以最简单的方式力求全面介绍常用和常见python语法及相关特性. 本教程适用于有一定的编程(C/C++/Java/C#/js等)基础的人员. 作者-dwSun Python介 ...
最新文章
- 【java下午茶系列】java三重奏之封装
- 皮一皮:这年头,没看过火影还没法做医生了...
- 1. 金融数学中的随机变分法-Wiener空间与Wiener泛函
- 数据库视频总结一(概述)
- MySQL启动mycat分库分表报错Java HotSpotTM 64-Bit Server VM warning: ignoring option MaxPermSize=64M
- 完美国际真数苹果_章子怡玩出新花样,雷人造型别有韵味!和小苹果同框犹如亲姐妹...
- 抖音直播APP软件系统为什么能这么火?反映出的问题又会是什么?
- M1 Mac:支持 USB-C,但不完全支持
- DB First .edmx
- SpringBoot java配置类@Configuration 的两种写法
- ArcGIS学习总结(11)——创建点要素并计算对应经纬度
- Jprofiler激活码
- b站python_python学习 —— B站抢楼原理
- FAT32、exFAT、NTFS
- java 跳跃表_你真的了解跳跃表吗
- 【NLP】自然语言处理的语料库与词库
- Android笔记:自定义锁屏
- 【好用的办公软件】万彩办公大师教程丨标准安装版/绿色免安装版/离线版区别
- 苹果刷机服务器验证失败,iPhone手机刷机报错最全总结 教你学会分析手机问题出在哪...
- MATLAB中求最大/最小值max/min函数