#1. C++中的原生态类型,Python中的包装器
#examplePet.cpp
#include <pybind11/pybind11.h>
namespace py = pybind11;
struct Pet {
Pet(const std::string &name) : name(name) { }
void setName(const std::string &name_) { name = name_; }
const std::string &getName() const { return name; }
std::string name;
};
PYBIND11_MODULE(examplePet, m) {
py::class_<Pet>(m, "Pet")
.def(py::init<const std::string &>())//对应c++类构造函数
.def("setName", &Pet::setName)
.def("getName", &Pet::getName);
}
# 编译
g++ -O3 -Wall -shared -std=c++11 -undefined dynamic_lookup $(python3 -m pybind11 --includes) examplePet.cpp -o examplePet$(python3-config --extension-suffix)
# 使用
>>> import examplePet
>>> p = examplePet.Pet("Molly")
>>> print(p)
>>> p.getName()
'Molly'
>>> p.setName("Charly")
>>> p.getName()
'Charly'
#2. python中的原生态类型,c++中的包装器
c++想获取python中原生态的数据(tuple或者list),使用py::object;
各种接口见:Python types
# printlist.cpp
#include <iostream>
#include <pybind11/pybind11.h>
namespace py = pybind11;
#include <pybind11/stl.h>
void print_list(py::list my_list) {
for (auto item : my_list)
std::cout << item << " ";
}
PYBIND11_MODULE( printlist, m ){
m.doc() = "pybind11 example";
m.def("print_list", &print_list, "add two number" );
}
Python list没有以任何方式被转换;它只是被封装在C++ PY::list类中。它的核心仍然是一个Python对象。复制py::list将像在Python中进行常规的引用计算。将对象返回到Python只会删除包装器。
g++ -O3 -Wall -shared -std=c++11 -undefined dynamic_lookup $(python3 -m pybind11 --includes) printlist.cpp -o printlist$(python3-config --extension-suffix)
>>> import printvector2
>>> printvector2.print_vector([1, 2, 3])
1 2 3
#3. 原生态C++与Python类型之间的转换
#printvector.cpp
#include <iostream>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
void print_vector(const std::vector<int> &v) {
for (auto item : v)
std::cout << item << "\n";
}
PYBIND11_MODULE( printvector, m ){
m.doc() = "pybind11 example";
m.def("print_vector", &print_vector, "add two number" );
}
这与前两种情况不一样;pybind11 创建了一个新的std::vector<int>
, 他的元素都是从python list中拷贝而来;std::vector<int>
传递给print_vector
时,其元素也会拷贝给一个新的python list;对于大数据这是一个耗时耗资源的过程。
g++ -O3 -Wall -shared -std=c++11 -undefined dynamic_lookup $(python3 -m pybind11 --includes) printvector.cpp -o printvector$(python3-config --extension-suffix)
import printvector
printvector.print_vector([1, 2, 3])
更多数据类型转换见:List of all builtin conversions
python的包装数据类型包括 handle
, object
, bool_
, int_
, float_
, str
, bytes
, tuple
,list
, dict
, slice
, none
, capsule
, iterable
, iterator
, function
, buffer
, array
, 和array_t
.
# 原文
网友评论