




已阅读5页,还剩4页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
这个问题是在我尝试利用pygraphviz嵌入我的C+代码绘制二叉树的时候发现的.找了半天资料,这里我把几种常用的C+调用PYTHON利用 boost.python 的方法作一个总结,希望能让别人少走弯路,因为有些内容还找不到中文文档,虽然都不难但是开始摸索还是费时间的. 我个人认为boost.python真的是非常的COOL,基本上不需要去学习那个看了就头大用着也不方便的python c api了,唯一的缺点是目前相关的资料太少,甚至官网上也解释不够详细. 前面我写了一篇python嵌入c+的入门文章包括安装和环境配置,介绍了如何利用 boost.python方便的传递C+代码中的参数,调用 python函数.boost.python入门教程 -python 嵌入c+这个boost.python官网上的tourial也有介绍. 首先第一种常用方式是 python:boost:exec#includeusingnamespaceboost:python; /引入python解释器Py_Initialize();/引入_main_作用域objectmain_module=import(_main_);objectmain_namespace=main_module.attr(_dict_);exec(print(Helloworld!),main_namespace);/exec + python command string + 作用域 第二种方法是利用boost:python:object对象第一种方法虽然很好但是不方便和C+交互数据,如传递C+中的数据作为参数给python函数,以及C+接受python执行函数后的返回值. 那么怎么用object调用python函数呢,很简单看下面的代码就了解了.我在simple.py中定义了函数def foo(int i = 3):return i + 2008 这样一个简单的函数, 通过将simple.py利用boost:python:exec_file将其引入到_main_作用域,我们在_main_._dict_ 也就是main_namespace中取到命名为foo的函数对象,并将其转换成boost:python:object使用. 这里我们给这个object同样命名为foo,调用foo(5)即调用python 函数foo(5)返回2013,注意在C+环境中要用extract将这个值取到. objectsimple=exec_file(simple.py,main_namespace,main_namespace);objectfoo=main_namespacefoo;intval=extract(foo(5);coutPythonhascaculatedfooasvalendl; 和C+不同,python函数支持不定长参数和关键字参数,遇到这种情况如何调用呢?如果是简单的foo(a,b,c)这样的python函数按照上面的形式调用即可,但是象foo(*args), foo(*kargs),foo(*args,*kargs)foo(n,*kargs)诸如此类的函数怎么在C+中利用boost:python:object调用呢? 恩,这是本文的重点,先看下什么是不定长参数和关键字参数.我直接copy一下赖勇浩博客上的解释吧,非常的清晰. /lanphaday/archive/2009/05/08/4159346.aspx不定参数 在 C/C+ 中,不定参数可以算得上一节提高篇的课程。因为它的 va_list、va_start和 va_end 等是侵入式的,理解起来并不容易;此外由于 C/C+ 都是静态强类型语言,在运行时数据并不携带类型信息,因此不定参数函数更像是一个调用协议,需要函数定义者和使用者之间通过文档、注释等方式进行沟通;或 者像 printf() 函数那样用 fmt 参数隐式指出参数类型,然后进行显式转型。 不定参数在 Python 中则简单得多。再回过头来年一下 C/C+,其实 va_list,完全是一个 tuple 实现,因为它可以持有不同数据类型的指针(通过void* 来实现)。得益于 Python 函数调用时的 boxing 和 unboxing 操作,Python 可以为不定参数的存取提供更为简洁的实现。如:def foo(*args): for arg in args: print arg在 Python 中可以使用 *args 语法为函数定义不定参数,其中 args 相当于 C/C+ 的 va_list,它是一个 tuple 类型的参数容器,所以无需所谓的 va_start、va_end 就可以简单遍历所有参数了。 在 Python 中,不定参数可以直接用 tuple 参数调用,如:names = (laiyonghao, denggao, liming)foo(*names) # 留意符号 *关键字参数尽管不定参数给函数带来了很多便利性,但 Python 的关键字参数尤为神通广大。关键字参数是指以下形式定义的参数:def foo(*kw): pass其中 kw 本质上是一个 dict 对象,所以可以这样调用 foo:foo( *a : 1, b : 2, c : 3 )看起来有点眼熟?对的,在“第一贴”(/lanphaday/archive/2008/08/31/2857813.aspx)里 DIP 的例 2.1 就有这几行代码:if _name_ = _main_: myParams = server:mpilgrim, database:master, uid:sa, pwd:secret print buildConnectionString(myParams)这个 buildConnectionString(myParams) 和前文的 foo() 调用很像吧,而且利用关键字参数后更复杂了。其实不是这样的,如果使用关键字参数,例2.1 可以写得优为简洁:def buildConnectionString(*params): Build a connection string from a dictionary of parameters. Returns string. return ;.join(%s=%s % (k, v) for k, v in params.iteritems()if _name_ = _main_: print buildConnectionString( server = mpilgrim, database = master uid = sa pwd = secret)除了更加优雅外,也比以前一种写法提升性能呢。本文来自CSDN博客,转载请标明出处:/lanphaday/archive/2009/05/08/4159346.aspxOK,下面重点介绍boost.python中怎么在C+中调用这样的带有不定参数,关键字参数的函数呢?torial 里面并没有介绍,那么我们去看boost:python:object的manu吧.或者 直接看源代码 template class object_operators : public def_visitor public: / function call / object operator()() const; detail:args_proxy operator* () const; object operator()(detail:args_proxy const &args) const; object operator()(detail:args_proxy const &args, detail:kwds_proxy const &kwds) const; 这个正是我们所需要的,()操作符重载,从而支持不定参数,上面红色的第一个函数,和不定参数+关键字参数,红色的第二个函数.Class template object_operators observer functionsobject operator()() const;template object operator()(A0 const&) const;template object operator()(A0 const&, A1 const&) const;.template object operator()(A0 const& a1, A1 const& a2,.An const& aN) const;Effects: call(object(*static_cast(this).ptr(), a1, a2,.aN) 这个对应普通的python 函数调用object operator()(detail:args_proxy const &args) const; Effects: call object with arguments given by the tuple args 对应不定参数的python函数调用object operator()(detail:args_proxy const &args, detail:kwds_proxy const &kwds) const; Effects: call object with arguments given by the tuple args, and named arguments given by the dictionary kwds 对应不定参数+关键字参数 dict的python函数的调用 OK,现在所有的python函数我们都可以在c+中利用boost:python:object调用了!很COOL吧! 看一个具体的例子: 在我试图在我的C+程序中使用pygraphviz的时候,我需要调用下面这样一个python函数.add_node(self, n, *attr) method of pygraphviz.agraph.AGraph instance Add a single node n. If n is not a string, conversion to a string will be attempted. String conversion will work if n has valid string representation (try str(n) if you are unsure). G=AGraph() G.add_node(a) G.nodes() a G.add_node(1) # will be converted to a string G.nodes() a, 1 Attributes can be added to nodes on creation G.add_node(2,color=red)该参数列表由一个普通参数和一个关键字参数构成,你可能会想上面的几种operator()的重载函数中没有这种形式啊?没有关系,解决的办法是将普通参数在这里当作tuple看待,而且你只能这么做:)否则运行通不过的! 具体的办法是如果你的函数有n 个普通参数在关键字参数前面那么你就生成并传递一个有n个元素组成的tuple,如果是形如foo(*kargs)这样的函数,那么你也需要先传递一个空tuple, void sort(args_proxy const &args, kwds_proxy const &kwds); x.sort(*tuple(), *dict(make_tuple(make_tuple(reverse, true); / 等价于 Python 调用 x.sort(reverse=true) 好了下面看一下我调用add_node的代码,注意add_node(1, color=red)表示生成一个node,它的关键字是1,而颜色是红色,我也可能会调用 add _node(2, lable=abc)表示该节点关键字是2,而它将会被输出显示的标志是abc.voidprint(std:stringresult=huff_tree.dot)usingnamespaceboost:python;/fortreeprintingPy_Initialize();objectmain_module=import(_main_);objectmain_namespace=main_module.attr(_dict_);exec(importpygraphvizaspgv,main_namespace);exec(tree_graph=pgv.AGraph(directed=True,strict=True),main_namespace);objecttree_graph=main_namespacetree_graph;tree_graph.attr(add_node)(*make_t
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024-2025学年浙江省杭州市临安区人教版六年级下册期中测试数学试卷(解析版)
- 药监局二法知识培训课件
- 等离激元提高钙钛矿基太阳能电池性能的研究构架
- 药店员工基础知识培训课件
- 科普知识培训会简报课件
- 科普安防知识培训内容课件
- 交易型受贿犯罪的深度剖析与实践审视:法理、认定与防范
- 理论宣传培训课件模板
- 电销的培训课件
- 利用遥感技术进行农业决策的协议
- 烟花爆竹理论题目及答案
- 苏教版2025-2026秋三年级数学上册教学计划及课时安排
- 北师大版五年级下册数学口算题题库1200道带答案可打印
- 托管老师岗前培训
- DB32T3916-2020建筑地基基础检测规程
- (正式版)HGT 6313-2024 化工园区智慧化评价导则
- 新苏教版六年级上册《科学》全一册全部课件(含19课时)
- 河南某高速公路改扩建工程盖板涵洞施工方案
- 客情关系维护
- 山东省道路运输协会第二的任职情况
- 德尔菲法案例分析
评论
0/150
提交评论