首页 > 代码库 > Python.boost学习笔记(4)
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(); } };
在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 >>>
Python.boost学习笔记(4)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。