c++ pybind11:如何使用上下文管理器实现

8iwquhpp  于 2023-08-09  发布在  其他
关注(0)|答案(2)|浏览(117)

我正在尝试用pybind11实现一个带有上下文管理器的Python。
根据Python的文档,我的第一个版本是:

py::class_<MyResource> (module, "CustomResource", "A custom ressource")
    .def("__enter__", [&] (MyResource& r) { r.lock(); }
        , "Enter the runtime context related to this object")
    .def("__exit__", [&] (MyResource& r, void* exc_type, void* exc_value, void* traceback) { r.unlock(); }
        , "Exit the runtime context related to this object")
    ;

字符串
我不知道exc_typeexc_valuetraceback的类型。我猜它们可以是简单的pybind11::object
它们是更具体的绑定,我可以使用吗?

gijlo24d

gijlo24d1#

实际上,这些参数将作为Python对象出现,因此应该使用pybind11::object类型。使用void*不是解决方案。
Pybind11可能是目前使用C作为其语言的C机制的最佳Python Package 器。

vltsax25

vltsax252#

将所有内容都设置为pybind11::object可以很好地工作,但是如果你想更具体一点,你可以将exc_type设置为std::optional<pybind11::type>,因为exc_type将始终是None或Python类型,例如。

.def("__exit__",
     [&] (MyResource& r,
          const std::optional<pybind11::type> &exc_type,
          const std::optional<pybind11::object> &exc_value,
          const std::optional<pybind11::object> &traceback)
     { 
              r.unlock(); 
     },
     "Exit the runtime context related to this object")

字符串
但是,由于std::optional仅在C17中添加,因此只能在不支持C11或C++14的情况下执行此操作。

相关问题