pybind11—類提鸟,結(jié)構(gòu)體

前言

在C++代碼中伏伐, 類(class)的使用頻率非常高, 將數(shù)據(jù)和對數(shù)據(jù)的操作方法封裝在一起帕翻,使得代碼的抽象層次增加。如何將C++中定義好的類在python中調(diào)用?下面舉例簡單說明萝风。


開發(fā)/測試環(huán)境

  • windows 10, 64bit
  • Anaconda3, with python 3.7
  • pycharm
  • visaul studio 2017

示例一

定義一個簡單的類

class Student {

public:
    std::string name;
    std::string gender;
    int age;

public:
    Student() {}
    Student(std::string name, std::string gender, int age) {
        this->name = name;
        this->gender = gender;
        this->age = age;
    }
    ~Student() {};

public:
    //setter
    void setName(std::string name) {
        this->name = name;
    }

    void setGender(std::string gender) {
        this->gender = gender;
    }

    void setAge(int age) {
        this->age = age;
    }

    //getter
    std::string getName() {
        return this->name;
    }

    std::string getGender() {
        return this->gender;
    }

    int getAge() {
        return this->age;
    }

};

編寫python擴展



PYBIND11_MODULE(example, m) {
    // Studnet
    py::class_<Student>(m, "Student")
        .def(py::init<std::string, std::string, int>())
        .def("setName", &Student::setName)
        .def("setGender", &Student::setGender)
        .def("setAge", &Student::setAge)
        .def("getName", &Student::getName)
        .def("getGender", &Student::getGender)
        .def("getAge", &Student::getAge);

}

編譯生成python擴展

image.png

image.png

測試代碼

image.png

image.png

靜態(tài)方法

image.png
image.png

代碼

class Student {

public:
    std::string name;
    std::string gender;
    int age;
    
public:
    Student() {}
    Student(std::string name, std::string gender, int age) {
        this->name = name;
        this->gender = gender;
        this->age = age;
    }
    ~Student() {};

public:
    //setter
    void setName(std::string name) {
        this->name = name;
    }

    void setGender(std::string gender) {
        this->gender = gender;
    }

    void setAge(int age) {
        this->age = age;
    }

    //getter
    std::string getName() {
        return this->name;
    }

    std::string getGender() {
        return this->gender;
    }

    int getAge() {
        return this->age;
    }

public:
    //聲明靜態(tài)成員
    static std::string university;

    // static method
    static std::string getUniversity() {
        return university;
    }

};

// 定義并且初始化static變量
std::string Student::university = "Xidian University";

PYBIND11_MODULE(example, m) {
    //py::class_<Pet>(m, "Pet")
    //  .def(py::init<const std::string &>())
    //  .def("setName", &Pet::setName)
    //  .def("getName", &Pet::getName);

    // Studnet
    py::class_<Student>(m, "Student")
        .def(py::init<std::string, std::string, int>())
        .def("setName", &Student::setName)
        .def("setGender", &Student::setGender)
        .def("setAge", &Student::setAge)
        .def("getName", &Student::getName)
        .def("getGender", &Student::getGender)
        .def("getAge", &Student::getAge)
        .def_static("getUniversity", &Student::getUniversity);  //def_static() 靜態(tài)方法

}

image.png

例子2

定義一個Person類, 包含:

  • 無參構(gòu)造函數(shù)
  • 含參構(gòu)造函數(shù)
  • private成員變量
  • public成員變量
  • static靜態(tài)成員變量
  • static靜態(tài)函數(shù)
  • setter/getter函數(shù)

class Person
{

public:
    std::string habbit;             //興趣愛好

private:
    std::string name;               //姓名
    std::string gender;             //性別
    int age;                        //年齡
    std::string idCardNum;          //身份證號碼
    std::string address;            //住址

public:
    void setName(std::string name) {
        this->name = name;
    }

    void setAge(int age) {
        this->age = age;
    }

    void setGender(std::string gender) {
        this->gender = gender;
    }

    void setAddress(std::string address) {
        this->address = address;
    }

    void setIdCardNum(std::string idCardNum) {
        this->idCardNum = idCardNum;
    }

    std::string getName() {
        return this->name;
    }

    std::string getGender() {
        return this->gender;
    }

    int getAge() {
        return this->age;
    }

    std::string getAddress() {
        return this->address;
    }

    std::string getIdCardNum() {
        return this->idCardNum;
    }


public:
    //
    static std::string university;
    static std::string getUniversity() {
        return university;
    }

public:
    Person() {};
    Person(std::string name, std::string gender, int age) {
        this->name = name;
        this->gender = gender;
        this->age = age;
    }
    ~Person() {};

};

std::string Person::university = "xidian University";

python擴展代碼

  • def(py::init()) python中構(gòu)造方法嘀掸,無參數(shù)

  • .def(py::init<std::string, std::string, int>()) 構(gòu)造方法,含參數(shù)

  • .def("setName", &Person::setName) set()方法

  • .def("getName", &Person::getName) get()方法

  • .def_static("getUniversity", &Person::getUniversity) static靜態(tài)方法

  • .def_readonly_static("university", &Person::university) static靜態(tài)只讀成員

  • .def_readwrite("habbit", &Person::habbit) 可讀可寫成員

對于C++ classprivate成員:

image.png

.def_property("name", &Person::getName, &Person::setName)
        .def_property("age", &Person::getAge, &Person::setAge)
        .def_property("gender", &Person::getGender, &Person::setGender)
        .def_property("address", &Person::getAddress, &Person::setAddress)
        .def_property("idCardNum", &Person::getIdCardNum, &Person::setIdCardNum);

完整代碼

#include<iostream>
#include<pybind11/pybind11.h>

namespace py = pybind11;

class Person
{

public:
    std::string habbit;             //興趣愛好

private:
    std::string name;               //姓名
    std::string gender;             //性別
    int age;                        //年齡
    std::string idCardNum;          //身份證號碼
    std::string address;            //住址

public:
    void setName(std::string name) {
        this->name = name;
    }

    void setAge(int age) {
        this->age = age;
    }

    void setGender(std::string gender) {
        this->gender = gender;
    }

    void setAddress(std::string address) {
        this->address = address;
    }

    void setIdCardNum(std::string idCardNum) {
        this->idCardNum = idCardNum;
    }

    std::string getName() {
        return this->name;
    }

    std::string getGender() {
        return this->gender;
    }

    int getAge() {
        return this->age;
    }

    std::string getAddress() {
        return this->address;
    }

    std::string getIdCardNum() {
        return this->idCardNum;
    }


public:
    //
    static std::string university;
    static std::string getUniversity() {
        return university;
    }

public:
    Person() {};
    Person(std::string name, std::string gender, int age) {
        this->name = name;
        this->gender = gender;
        this->age = age;
    }
    ~Person() {};

};

std::string Person::university = "xidian University";


PYBIND11_MODULE(demo3, m) {

    m.doc() = "Simple Class";
    
    py::class_<Person>(m, "Person")
        .def(py::init())
        .def(py::init<std::string, std::string, int>())
        .def("setName", &Person::setName)
        .def("setAge", &Person::setAge)
        .def("setGender", &Person::setGender)
        .def("setAddress", &Person::setAddress)
        .def("getName", &Person::getName)
        .def("getAge", &Person::getAge)
        .def("getGender", &Person::getGender)
        .def("getAddress", &Person::getAddress)
        .def_static("getUniversity", &Person::getUniversity)
        .def_readonly_static("university", &Person::university)
        .def_readwrite("habbit", &Person::habbit)
        .def_property("name", &Person::getName, &Person::setName)
        .def_property("age", &Person::getAge, &Person::setAge)
        .def_property("gender", &Person::getGender, &Person::setGender)
        .def_property("address", &Person::getAddress, &Person::setAddress)
        .def_property("idCardNum", &Person::getIdCardNum, &Person::setIdCardNum);


}

在pycharm中測試

將vs生成的lib和pyd文件復制到python代碼所在目錄规惰, 直接import即可:


image.png

python代碼

person1 = demo3.Person()
person1.name = 'tianyu'
person1.age = 23
person1.gender = 'female'
print(person1.getName())
print(person1.getAge())
print(person1.getGender())
print(person1.university)

測試結(jié)果

image.png

image.png
image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末睬塌,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子歇万,更是在濱河造成了極大的恐慌揩晴,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件贪磺,死亡現(xiàn)場離奇詭異硫兰,居然都是意外死亡,警方通過查閱死者的電腦和手機寒锚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進店門劫映,熙熙樓的掌柜王于貴愁眉苦臉地迎上來违孝,“玉大人,你說我怎么就攤上這事泳赋〈粕#” “怎么了?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵祖今,是天一觀的道長校坑。 經(jīng)常有香客問我,道長千诬,這世上最難降的妖魔是什么耍目? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮大渤,結(jié)果婚禮上制妄,老公的妹妹穿的比我還像新娘。我一直安慰自己泵三,他們只是感情好耕捞,可當我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著烫幕,像睡著了一般俺抽。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上较曼,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天磷斧,我揣著相機與錄音,去河邊找鬼捷犹。 笑死弛饭,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的萍歉。 我是一名探鬼主播侣颂,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼枪孩!你這毒婦竟也來了憔晒?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤蔑舞,失蹤者是張志新(化名)和其女友劉穎拒担,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體攻询,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡从撼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年颊亮,在試婚紗的時候發(fā)現(xiàn)自己被綠了邮破。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片体捏。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡染苛,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出毁兆,到底是詐尸還是另有隱情浙滤,我是刑警寧澤,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布气堕,位于F島的核電站纺腊,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏茎芭。R本人自食惡果不足惜揖膜,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望梅桩。 院中可真熱鬧壹粟,春花似錦、人聲如沸宿百。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽垦页。三九已至雀费,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間痊焊,已是汗流浹背盏袄。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留薄啥,地道東北人辕羽。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像垄惧,于是被迫代替她去往敵國和親刁愿。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,914評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 包(lib)赘艳、模塊(module) 在Python中,存在包和模塊兩個常見概念克握。 模塊:編寫Python代碼的py...
    清清子衿木子水心閱讀 3,805評論 0 27
  • 一蕾管、快捷鍵 ctr+b 執(zhí)行ctr+/ 單行注釋ctr+c ...
    o_8319閱讀 5,816評論 2 16
  • 這是16年5月份編輯的一份比較雜亂適合自己觀看的學習記錄文檔,今天18年5月份再次想寫文章菩暗,發(fā)現(xiàn)簡書還為我保存起的...
    Jenaral閱讀 2,756評論 2 9
  • 寫在前面的話 代碼中的# > 表示的是輸出結(jié)果 輸入 使用input()函數(shù) 用法 注意input函數(shù)輸出的均是字...
    FlyingLittlePG閱讀 2,758評論 0 8
  • 節(jié)都快要過完了停团,還沒去看過廟會旷坦。 我倒是無所謂掏熬,奈何女人孩子呆不住。 那就浪起來秒梅! 孩子一看到游樂設(shè)備就開心不已旗芬,...
    浮生夢一場閱讀 158評論 0 3