要实现 pickling,
__setstate__()
可以通过以下方式添加到 C 中的 Pybind11 对象中 pybind11 文档。在这个官方示例中,创建了一个新对象(Pickleable),根据给定状态更新并返回。然而,据我从大多数常规 Python 示例中发现,__setstate__()
应该更新它self
的值。我想知道为什么 pybind11 的逻辑与常规 Python 不同。或者我们还能以某种方式更新调用对象吗?
来自文档:
py::class_<Pickleable>(m, "Pickleable")
...
.def(py::pickle(
...
[](py::tuple t) { // __setstate__
if (t.size() != 2)
throw std::runtime_error("Invalid state!");
/* Create a new C++ instance */
Pickleable p(t[0].cast<std::string>()); // <-- Why create a new instance instead of updating *this*?
p.setExtra(t[1].cast<int>());
return p;
}
));
这就是我认为
__setstate__
部分应该做的事情:
py::class_<Pickleable>(m, "Pickleable")
...
.def(py::pickle(
...
[](Pickleable &p, py::tuple t) { // __setstate__
if (t.size() != 2)
throw std::runtime_error("Invalid state!");
p.setExtra(t[1].cast<int>());
}
));
确实 Python
pickle.loads()
总是返回一个新对象。但是,我问这个是因为我想直接使用 __setstate__
来更新现有的 Pybind11 对象。是的,我确实可以为我的目的创建另一个 setstate
,但是为什么创建两个函数只是做同样的事情呢?