pickle2.cpp 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. // Copyright Ralf W. Grosse-Kunstleve 2002-2004. Distributed under the Boost
  2. // Software License, Version 1.0. (See accompanying
  3. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  4. /*
  5. This example shows how to make an Extension Class "pickleable".
  6. The world class below contains member data (secret_number) that
  7. cannot be restored by any of the constructors. Therefore it is
  8. necessary to provide the __getstate__/__setstate__ pair of pickle
  9. interface methods.
  10. For simplicity, the __dict__ is not included in the result of
  11. __getstate__. This is not generally recommended, but a valid
  12. approach if it is anticipated that the object's __dict__ will
  13. always be empty. Note that safety guards are provided to catch
  14. the cases where this assumption is not true.
  15. pickle3.cpp shows how to include the object's __dict__ in the
  16. result of __getstate__.
  17. For more information refer to boost/libs/python/doc/pickle.html.
  18. */
  19. #include <boost/python/module.hpp>
  20. #include <boost/python/def.hpp>
  21. #include <boost/python/class.hpp>
  22. #include <boost/python/tuple.hpp>
  23. #include <boost/python/extract.hpp>
  24. namespace boost_python_test {
  25. // A friendly class.
  26. class world
  27. {
  28. public:
  29. world(const std::string& _country) : secret_number(0) {
  30. this->country = _country;
  31. }
  32. std::string greet() const { return "Hello from " + country + "!"; }
  33. std::string get_country() const { return country; }
  34. void set_secret_number(int number) { secret_number = number; }
  35. int get_secret_number() const { return secret_number; }
  36. private:
  37. std::string country;
  38. int secret_number;
  39. };
  40. struct world_pickle_suite : boost::python::pickle_suite
  41. {
  42. static
  43. boost::python::tuple
  44. getinitargs(const world& w)
  45. {
  46. return boost::python::make_tuple(w.get_country());
  47. }
  48. static
  49. boost::python::tuple
  50. getstate(const world& w)
  51. {
  52. return boost::python::make_tuple(w.get_secret_number());
  53. }
  54. static
  55. void
  56. setstate(world& w, boost::python::tuple state)
  57. {
  58. using namespace boost::python;
  59. if (len(state) != 1)
  60. {
  61. PyErr_SetObject(PyExc_ValueError,
  62. ("expected 1-item tuple in call to __setstate__; got %s"
  63. % state).ptr()
  64. );
  65. throw_error_already_set();
  66. }
  67. long number = extract<long>(state[0]);
  68. if (number != 42)
  69. w.set_secret_number(number);
  70. }
  71. };
  72. }
  73. BOOST_PYTHON_MODULE(pickle2_ext)
  74. {
  75. using namespace boost_python_test;
  76. boost::python::class_<world>(
  77. "world", boost::python::init<const std::string&>())
  78. .def("greet", &world::greet)
  79. .def("get_secret_number", &world::get_secret_number)
  80. .def("set_secret_number", &world::set_secret_number)
  81. .def_pickle(world_pickle_suite())
  82. ;
  83. }