前言
在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++ class中private成員:
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