最近在用 pybind11 绑定 c++中的一个库到 Python 中,遇到了一个问题
待绑定的类方法如下
class Ciphertext
{
public:
inline auto &scale() noexcept
{
return scale_;
}
inline auto &scale() const noexcept
{
return scale_;
}
private:
double scale_ = 1.0;
}
其例子中,有这样的调用:
Ciphertext x1_encrypted
x1_encrypted.scale() = pow(2.0, 40)
我是这样绑定的,可以成功访问到 scale 的值:
py::class_<Ciphertext>(m, "Ciphertext")
.def("scale", (double &(Ciphertext::*)()) &Ciphertext::scale)
但是,显然不能这样在 python 中给它赋值,请问有什么方法?还是说,只能自己去增加 set 方法?
谢谢各位了!
1
ysc3839 2019-07-22 13:38:56 +08:00 via Android 1
C++ 这样是返回了引用,我印象中 Python 没有等价的写法吧?建议按 Python 的风格弄成 getter setter。
|
3
ysc3839 2019-07-22 14:05:24 +08:00 via Android
@Huelse 并不建议这么做,可以用 def_property 定义成可直接读写的属性。
https://pybind11.readthedocs.io/en/stable/classes.html#instance-and-static-fields 另外看文档也许可以试试 def_readwrite ? |
4
Huelse OP @ysc3839 #3 试过了,不可行,def_property 需要 set 和 get,c++里没有,def_readwrite 会说 scale 是私有的
|
5
guiqiqi 2019-07-22 16:21:08 +08:00 via iPhone 1
最近正在用,我不想搞成 python 那种 getter setter 的方法,于是选择了函数重载,也蛮好用的,仅供参考
|
6
Valyrian 2019-07-22 16:22:08 +08:00
把 int 包成 class 然后返回引用(逃
|
10
Huelse OP @ysc3839 #9 嗯嗯,了解,我现在想另一个问题
@guiqiqi #8 想请你们看下 ``` template<typename T, typename = std::enable_if_t<std::is_same<T, double>::value || std::is_same<T, std::complex<double>>::value>> inline void decode(const Plaintext &plain, std::vector<T> &destination, MemoryPoolHandle pool = MemoryManager::GetPool()) { decode_internal(plain, destination, std::move(pool)); } ``` 这种 template 怎么绑定 是参照这个嘛? https://github.com/pybind/pybind11/blob/master/tests/test_opaque_types.cpp https://github.com/pybind/pybind11/issues/1854 |
12
Huelse OP |
14
Huelse OP @ysc3839 #13
就是我 list 变量放进函数里进行操作,按照 Python 的内存管理,显然不会对函数外的 list 产生影响 现在我想在不改变 c++代码的情况下,通过 pybind11 绑定完成 list 变量生成 |
15
Huelse OP @ysc3839 #13 按文档里说的,应该是声明 std::vector<double>opaque 类型就可以了
https://pybind11.readthedocs.io/en/stable/advanced/cast/stl.html 但是,我不知道为啥,还是不行。 |
16
Huelse OP @ysc3839 #13 我想我大概有办法了,我重新定义了一个 py::class_<DoubleVector>(m, "DoubleVector"),
现在想怎么把 operator[]加进去,方便 python 里直接 list[123]这样直接索引赋值 |
17
Huelse OP @ysc3839 #13 我想我大概有办法了,我重新定义了一个 PYBIND11_MAKE_OPAQUE(std::vector<double>); py::class_<DoubleVector>(m, "DoubleVector"),
现在想怎么把 operator[] 加进去,方便 python 里直接 list[123]这样直接索引赋值 |
18
guiqiqi 2019-07-23 00:34:15 +08:00 via iPhone
@Huelse 不好意思才看到,我没有读懂你的问题;因为 python 传参数如果是可变量也是引用的,如果你要是要传入 CPP 的函数里,我没这么操作过抱歉帮不到你,但是为什么不在 CPP 里生成好再传出来呢 :) 虽说是胶水语言,但毕竟一层干一层的事情嘛。
我用的是 boost::python,pybind 看起来像是在其上又封装了一层,绑定机制什么的看起来都一样的。如果 pybind 文档少,你可以查查 boost 的相关资料。 |