使用ffpython嵌入和扩展python

简介: ffpython ffpython is a c++ lib,which is to simplify task that embed python and extend python. For example, call python function, register c++ function to python, register c++ class to python.

ffpython

ffpython is a c++ lib,which is to simplify task that embed python and extend python. For example, call python function, register c++ function to python, register c++ class to python. Only one implement c++ header file.

Project Goals

  • easier to embed python script
  • easier to call python function
  • easier to set or get var in python script
  • easier to extend python with c++ static function
  • easier to extend python with c++ class. C++ class Once registed, python can use it like builtin type.
  • when python exception throw, ffpython will wrap it as a std exception which includes python traceback info.

Supported Python versions

  • python2.5 python2.6 python2.7, win / linux
  • python3.x is being developed, but unfortunately, python3.x api is so different to python2.x, even diffent between python3.2 and python3.3, Headache!!

Embed Python script in C++

Get / Set varialbe in python script/module

printf("sys.version=%s\n", ffpython.get_global_var<string>("sys", "version").c_str());
    ffpython.set_global_var("fftest", "global_var", "OhNice");
    printf("fftest.global_var=%s\n", ffpython.get_global_var<string>("fftest", "global_var").c_str());

 

call python function, Support all base type as arg or return value. Nine args can be supported.

int a1 = 100; float a2 = 3.14f; string a3 = "OhWell";
    ffpython.call<void>("fftest", "test_base", a1, a2, a3);

 

call python function, Support all STL type as arg or return value. Nine args can be supported. Vector and List for tuple and list in python,map for dict in python.

vector<int> a1;a1.push_back(100);a1.push_back(200);
    list<string> a2; a2.push_back("Oh");a2.push_back("Nice");
    vector<list<string> > a3;a3.push_back(a2);

    ffpython.call<bool>("fftest", "test_stl", a1, a2, a3);
    typedef map<string, list<vector<int> > > ret_t;
    ret_t val = ffpython.call<ret_t>("fftest", "test_return_stl");

 

Extend Python

register c++ static function, all base type supported. Arg num can be nine.

static int print_val(int a1, float a2, const string& a3, const vector<double>& a4)
{
    printf("%s[%d,%f,%s,%d]\n", __FUNCTION__, a1, a2, a3.c_str(), a4.size());
    return 0;
}
struct ops_t
{
    static list<int> return_stl()
    {
        list<int> ret;ret.push_back(1024);
        printf("%s\n", __FUNCTION__);
        return ret;
    }
};

void test_reg_function()
{
    ffpython_t ffpython;//("ext1");
    ffpython.reg(&print_val, "print_val")
            .reg(&ops_t::return_stl, "return_stl");
    ffpython.init("ext1");
    ffpython.call<void>("fftest", "test_reg_function");
}

 

register c++ class, python can use it just like builtin types.

class foo_t
{
public:
    foo_t(int v_):m_value(v_)
    {
        printf("%s\n", __FUNCTION__);
    }
    virtual ~foo_t()
    {
        printf("%s\n", __FUNCTION__);
    }
    int get_value() const { return m_value; }
    void set_value(int v_) { m_value = v_; }
    void test_stl(map<string, list<int> >& v_) 
    {
        printf("%s\n", __FUNCTION__);
    }
    int m_value;
};

class dumy_t: public foo_t
{
public:
    dumy_t(int v_):foo_t(v_)
    {
        printf("%s\n", __FUNCTION__);
    }
    ~dumy_t()
    {
        printf("%s\n", __FUNCTION__);
    }
    void dump() 
    {
        printf("%s\n", __FUNCTION__);
    }
};


static foo_t* obj_test(dumy_t* p)
{
    printf("%s\n", __FUNCTION__);
    return p;
}

void test_register_base_class(ffpython_t& ffpython)
{
    ffpython.reg_class<foo_t, PYCTOR(int)>("foo_t")
            .reg(&foo_t::get_value, "get_value")
            .reg(&foo_t::set_value, "set_value")
            .reg(&foo_t::test_stl, "test_stl")
            .reg_property(&foo_t::m_value, "m_value");

    ffpython.reg_class<dumy_t, PYCTOR(int)>("dumy_t", "dumy_t class inherit foo_t ctor <int>", "foo_t")
        .reg(&dumy_t::dump, "dump");

    ffpython.reg(obj_test, "obj_test");

    ffpython.init("ext2");
    ffpython.call<void>("fftest", "test_register_base_class");
};

 

Register c++ class which inherit a class having been registered.

ffpython.call<void>("fftest", "test_register_inherit_class");

 

C++ object pointer can be as a arg to python, and object can be access as a instance of builtin type in python.

void test_cpp_obj_to_py(ffpython_t& ffpython)
{
    foo_t tmp_foo(2013);
    ffpython.call<void>("fftest", "test_cpp_obj_to_py", &tmp_foo);
}
void test_cpp_obj_py_obj(ffpython_t& ffpython)
{
    dumy_t tmp_foo(2013);

    foo_t* p = ffpython.call<foo_t*>("fftest", "test_cpp_obj_py_obj", &tmp_foo);
}

 

Python test script

def test_base(a1, a2, a3):
    print('test_base', a1, a2, a3)
    return 0

def test_stl(a1, a2, a3):
    print('test_stl', a1, a2, a3)
    return True

def test_return_stl():
    print('test_return_stl')
    #map<string, list<vector<int> > >
    ret = {'Oh':[[111,222], [333, 444] ] }
    return ret

def test_reg_function():
    import ext1
    ext1.print_val(123, 45.6 , "----789---", [3.14])
    ret = ext1.return_stl()
    print('test_reg_function', ret)

def test_register_base_class():
    import ext2
    foo = ext2.foo_t(20130426)
    print("test_register_base_class get_val:", foo.get_value())
    foo.set_value(778899)
    print("test_register_base_class get_val:", foo.get_value(), foo.m_value)
    foo.test_stl({"key": [11,22,33] })
    print('test_register_base_class test_register_base_class', foo)

def test_register_inherit_class():
    import ext2
    dumy = ext2.dumy_t(20130426)
    print("test_register_inherit_class get_val:", dumy.get_value())
    dumy.set_value(778899)
    print("test_register_inherit_class get_val:", dumy.get_value(), dumy.m_value)
    dumy.test_stl({"key": [11,22,33] })
    dumy.dump()
    print('test_register_inherit_class', dumy)

def test_cpp_obj_to_py(foo):
    import ext2
    print("test_cpp_obj_to_py get_val:", foo.get_value())
    foo.set_value(778899)
    print("test_cpp_obj_to_py get_val:", foo.get_value(), foo.m_value)
    foo.test_stl({"key": [11,22,33] })
    print('test_cpp_obj_to_py test_register_base_class', foo)

def test_cpp_obj_py_obj(dumy):
    import ext2
    print("test_cpp_obj_py_obj get_val:", dumy.get_value())
    dumy.set_value(778899)
    print("test_cpp_obj_py_obj get_val:", dumy.get_value(), dumy.m_value)
    dumy.test_stl({"key": [11,22,33] })
    dumy.dump()
    ext2.obj_test(dumy)
    print('test_cpp_obj_py_obj', dumy)

    return dumy

 

Summary

  • ffpython Only One implement head file, it is easy to itegrate to project.
  • ffpython is simplely wrap for python api, so it is efficient.
  • source code https://github.com/fanchy/ffpython
目录
相关文章
|
24天前
|
算法 关系型数据库 程序员
程序员必备技能)基于Python的鼠标与键盘控制实战扩展与源码
这篇文章是关于如何使用Python的`pyautogui`库来控制鼠标和键盘进行各种操作,包括移动、点击、滚轮控制以及键盘的按键和快捷键输出,并介绍了如何结合图像处理和计算机视觉技术来扩展其应用。
|
1月前
|
测试技术 程序员 开发者
探索代码整洁之道:编写可维护和可扩展的Python程序
【8月更文挑战第3天】在编程的海洋中,我们经常追求的是那些能够高效运行、易于理解和维护的代码。本文将深入探讨如何通过遵循一系列的最佳实践来提升Python代码的整洁度,从而增强其可维护性和可扩展性。我们将通过具体示例,展示如何应用这些原则来编写更优雅、更健壮的Python程序。
21 0
|
3月前
|
数据安全/隐私保护 Python
Python装饰器是高阶函数,用于在不修改代码的情况下扩展或修改函数行为。它们提供可重用性、模块化和无侵入性的功能增强。
【6月更文挑战第20天】Python装饰器是高阶函数,用于在不修改代码的情况下扩展或修改函数行为。它们提供可重用性、模块化和无侵入性的功能增强。例如,`@simple_decorator` 包装`my_function`,在调用前后添加额外操作。装饰器还能接受参数,如`@logged(&quot;INFO&quot;, &quot;msg&quot;)`,允许动态定制功能。
28 6
|
2月前
|
存储 数据可视化 数据处理
`geopandas`是一个开源项目,它为Python提供了地理空间数据处理的能力。它基于`pandas`库,并扩展了其对地理空间数据(如点、线、多边形等)的支持。`GeoDataFrame`是`geopandas`中的核心数据结构,它类似于`pandas`的`DataFrame`,但包含了一个额外的地理列(通常是`geometry`列),用于存储地理空间数据。
`geopandas`是一个开源项目,它为Python提供了地理空间数据处理的能力。它基于`pandas`库,并扩展了其对地理空间数据(如点、线、多边形等)的支持。`GeoDataFrame`是`geopandas`中的核心数据结构,它类似于`pandas`的`DataFrame`,但包含了一个额外的地理列(通常是`geometry`列),用于存储地理空间数据。
|
3月前
|
数据采集 存储 中间件
Scrapy,作为一款强大的Python网络爬虫框架,凭借其高效、灵活、易扩展的特性,深受开发者的喜爱
【6月更文挑战第10天】Scrapy是Python的高效爬虫框架,以其异步处理、多线程及中间件机制提升爬取效率。它提供丰富组件和API,支持灵活的数据抓取、清洗、存储,可扩展到各种数据库。通过自定义组件,Scrapy能适应动态网页和应对反爬策略,同时与数据分析库集成进行复杂分析。但需注意遵守法律法规和道德规范,以合法合规的方式进行爬虫开发。随着技术发展,Scrapy在数据收集领域将持续发挥关键作用。
90 4
|
3月前
|
文字识别 API C++
技术好文共享:编写Tesseract的Python扩展
技术好文共享:编写Tesseract的Python扩展
25 0
|
3月前
|
Java C# C++
Python基础教程(第3版)中文版 第17章 扩展python (笔记)
Python基础教程(第3版)中文版 第17章 扩展python (笔记)
|
4月前
|
存储 算法 数据挖掘
R语言和Python用泊松过程扩展:霍克斯过程Hawkes Processes分析比特币交易数据订单到达自激过程时间序列
R语言和Python用泊松过程扩展:霍克斯过程Hawkes Processes分析比特币交易数据订单到达自激过程时间序列
|
4月前
|
开发者 Python
Python中的元编程:扩展语言的力量
【2月更文挑战第5天】本文将探讨Python中的元编程,介绍了元编程的概念和意义,并详细讨论了Python中常用的元编程技术,如装饰器、元类和动态类型。通过元编程,我们可以在不改变语言核心的情况下,扩展Python的功能和灵活性,为开发者提供更强大的工具和框架。
|
4月前
|
设计模式 Python
Python中的装饰器:优雅而强大的功能扩展工具
在Python中,装饰器是一种强大的功能扩展工具,它可以在不修改原始函数代码的情况下,动态地添加额外的功能。本文将深入探讨Python中装饰器的使用方法和应用场景,并结合实际案例详细介绍其实现原理及优雅的设计模式。