Python.boost学习笔记(4)

这一章首先通过一个封装简单的类来讲解如何封装类的constructor, method和data member. 

#include <boost/python.hpp>
#include <iostream>
using namespace boost::python; 

class animal
{
public:

  animal()
  {
    myLanguage="";
  };
  animal(std::string language)
  {
    myLanguage=language;
  };
  std::string get()
  {
    return myLanguage;
  }
  std::string myLanguage;
};
BOOST_PYTHON_MODULE(cry)
{
  class_<animal>("animal")
    .def(init<std::string>()) // wrap for multipole constructors
    .def("get",&animal::get)
    .def_readonly("language", &animal::myLanguage); // or set it as def_readwrite, note: for private member, we cannot wrap it here
}

封装类用boost的宏, BOOST_PYTHON_MODULE( module name)开始。 在module内定义需要被封装的部分: class_<被封装类>("module中对应的类的名称")加.def(方法名称, 方法对象)。 对于data member比较特殊,首先一定不能使private的,这个不管你怎么play都不会编译通过 (难道python不支持friend机制?)。 然后用.def_readonly就是不可以修改只可读,相当于const xxx的member,或者def_readwrite,
那么就是可读写。

编译运行测试:

Python 2.7.5 (default, Nov  3 2014, 14:26:24)
[GCC 4.8.3 20140911 (Red Hat 4.8.3-7)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import cry
>>> a=cry.animal()
>>> b=cry.animal("hello")
>>> print a.get()

>>> print b.get()
hello
>>> a.language
''
>>> b.language
'hello'
>>> b.language='test'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: can't set attribute
>>>

这种wrapper对于一般性的类有效,可惜在GUI下面。。。特别是邪恶的QT这种lib下面却是没什么用。。。。那么对已C++的继承和多态, python是如何封装的。。。

把上面的例子稍微做修改

#include <boost/python.hpp>
#include <iostream>
using namespace boost::python; 

class animal
{
public:

  animal()
  {
    myLanguage="";
  };
  animal(std::string language)
  {
    myLanguage=language;
  };
  std::string get()
  {
    return myLanguage;
  }
protected:
  std::string myLanguage;
};

class dog :public animal
{
public:

  dog()
  {
    myLanguage="bak bak";
  };
  dog(std::string language)
    :animal(language)
  {
  };
};

void myCry(animal* it)
{
  std::cout<<it->get()<<std::endl;
}

BOOST_PYTHON_MODULE(cry)
{
  class_<animal>("animal")
    .def(init<std::string>())
    .def("get",&animal::get);
  class_<dog, bases<animal> >("dog")
    .def(init<std::string>());
  def("myCry",myCry);
}

现在有一个叫做dog的类继承animal,他的constructor不同于animal, 有一个 myCry的function来test多态。

class_<dog, bases<animal> >("dog")
    .def(init<std::string>());

只要用bases<animal>, 就不需要再def get了,因为在animal里面已经被def过一次,wrapper自动继承过来。

Python 2.7.5 (default, Nov  3 2014, 14:26:24)
[GCC 4.8.3 20140911 (Red Hat 4.8.3-7)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import cry
>>> a=cry.animal()
>>> b=cry.dog()
>>> myCry(a)
>>> cry.myCry(a)

>>> cry.myCry(b)
bak bak

虚函数是另外一种需要处理的情形。这个wrapper需要从C++wrap一次之后再用boost wrap

那么再做简单的修改:

#include <boost/python.hpp>
#include <iostream>
using namespace boost::python; 

class animal
{
public:

  virtual std::string get()
  {
    return "Virtual animal, not implemented";
  }
  virtual ~animal(){};
};

class dog :public animal
{
public:
  virtual std::string get()
  {
    return "bak bak";
  }
  virtual ~dog(){};
};

// wrapper for animal
class animalWrap: public animal,public wrapper<animal>
{
public:
  std::string get()
  {
    if (override get=this->get_override("get"))
      return get();
    return animal::get();
  }
  std::string default_get()
  {
    return this->animal::get();
  }
};

void myCry(animal* it)
{
  std::cout<<it->get()<<std::endl;
}
BOOST_PYTHON_MODULE(cry)
{
  class_<animalWrap,boost::noncopyable>("animal")
    .def("get",&animal::get,&animalWrap::default_get);
  class_<dog, bases<animal> >("dog");
  def("myCry",myCry);
}

现在把get作为虚函数,返回string各不相同。 其中单独写的wrapper:

// wrapper for animal
class animalWrap: public animal,public wrapper<animal>
{
public:
  std::string get()
  {
    if (override get=this->get_override("get"))
      return get();
    return animal::get();
  }
  std::string default_get()
  {
    return this->animal::get();
  }
};

一个继承animal, 一个继承 wrapper<animal>, 第二个是boost给你做好的wrapper, 里面需要implement两个函数, get和default_get, get里面检查是不是有overload,如果是,返回overloaded,不是则返回父类的。至于为什么要一个default_get,我没读懂doc,但是照着做却是work. 有人懂的话告诉我。

在boost wrapper里面两个都要wrap

class_<animalWrap,boost::noncopyable>("animal")

.def("get",&animal::get,&animalWrap::default_get);

注意class_后面放的是wrap class name,并且加了个不知为什么的boost::noncopyable, 后面两个我们wrapper里都定义的function都放进去。

编译后在python中定义一个叫做cat的animal的子类,通过myCry来检测是否像预期一样的工作

>>> from cry import *
>>> a=animal()
>>> b=dog()
>>> class cat(animal):
...     def get(self):
...             return "miao miao"
...
>>> c=cat()
>>> myCry(a)
Virtual animal, not implemented
>>> myCry(b)
bak bak
>>> myCry(c)
miao miao
>>>
时间: 2024-10-11 23:16:03

Python.boost学习笔记(4)的相关文章

2. 蛤蟆Python脚本学习笔记二基本命令畅玩

2. 蛤蟆Python脚本学习笔记二基本命令畅玩 本篇名言:"成功源于发现细节,没有细节就没有机遇,留心细节意味着创造机遇.一件司空见惯的小事或许就可能是打开机遇宝库的钥匙!" 下班回家,咱先来看下一些常用的基本命令. 欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/48092873 1.  数字和表达式 看下图1一就能说明很多问题: 加法,整除,浮点除,取模,幂乘方等.是不是很直接也很粗暴. 关于上限,蛤蟆不太清楚

Python Click 学习笔记(转)

原文链接:Python Click 学习笔记 Click 是 Flask 的团队 pallets 开发的优秀开源项目,它为命令行工具的开发封装了大量方法,使开发者只需要专注于功能实现.恰好我最近在开发的一个小工具需要在命令行环境下操作,就写个学习笔记. 国际惯例,先来一段 "Hello World" 程序(假定已经安装了 Click 包). # hello.py import click @click.command() @click.option('--count', default

[简明python教程]学习笔记之编写简单备份脚本

[[email protected] 0503]# cat backup_ver3.py #!/usr/bin/python #filename:backup_ver3.py import os import time #source source=['/root/a.sh','/root/b.sh','/root/c.sh'] #source='/root/c.sh' #backup dir target_dir='/tmp/' today=target_dir+time.strftime('

3. 蛤蟆Python脚本学习笔记三字符串

3. 蛤蟆Python脚本学习笔记三字符串 本篇名言:"平静的湖面只有呆板的倒映,奔腾的激流才有美丽的浪花!幸福不是靠别人来布施,而是要自己去赢取!生命的意义在不断挑战自己,战胜自己!" 这个本来放在昨天的,由于昨晚又太晚了,所以就搁在这里了.赶紧看看吧. 字符串两边都用双引号或者单引号包起来.否则就使用转移符号来转移一下. 输入在一起可以直接拼接. 欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/48112507

1.蛤蟆Python脚本学习笔记一环境搭建

1.蛤蟆Python脚本学习笔记一环境搭建 蛤蟆一直在想在工作的时候能不能有一个牛逼的工具来让自己工作更加轻松和快乐.用过C, C++, C#, JAVA,  SHELL,TCL,汇编,BAT等,感觉这些都是需要的时候能发挥作用,不能和我想象的一样.突然有一天,感觉Python实在不错,那么就和小伙伴们一起乐呵乐呵呗.万事开头难,我们先来搭建环境吧. 欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/48058315 1. 相关

[简明python教程]学习笔记2014-05-05

今天学习了python的输入输出.异常处理和python标准库 1.文件 通过创建一个file类的对象去处理文件,方法有read.readline.write.close等 [[email protected] 0505]# cat using_file.py #!/usr/bin/python #filename:using_file.py poem='''Programing is fun when the work is done use Python! ''' f=file('poem.

[Python][MachineLeaning]Python Scikit-learn学习笔记1-Datasets&amp;Estimators

Scikit-learn官网:http://scikit-learn.org/stable/index.html Datasets 标准的数据集格式为一组多维特征向量组成的集合.数据集的标准形状(shape)为二维数组(samples, features),其中samples表示数据集大小,features表示其中特征向量的维数. 使用时可使用shape方法查看数据集 >>> from sklearn import datasets >>> iris = dataset

Python scikit-learn 学习笔记—环境篇

Python scikit-learn 学习笔记-环境篇 近来闲来无事,也面临毕业季.这段时间除了做毕业设计,和同学再多吃几顿饭玩玩游戏之外.剩下的时间浪费着实可惜.想着以后研究生还要读三年,不如现在多看看书或者别的资料.正逢最近参加阿里巴巴大数据比赛,趁机学了一阵Python 数据挖掘包scikit learn,估计以后说不定会用到,所以先行记录下来,分享给大家. 先说一下这段时间对sklearn的理解.这一个数据挖掘包给我最直观的感觉就是简易.这个挖掘包的一些算法核心编码部分是借鉴别的单独算

Python个人学习笔记四

                                        本节主要学习python语言中网络相关知识. 一 主要文件和目录在Urllib的request.py模块下面.其中支持SSL加密方式访问. 下面我们看看其中的主要类和函数吧. 先看看源码吧. def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, *, cafile=None, capath=None, cadefault=False):