c++ - 如何在包装类(来自 C++)中覆盖 __setattr__?

标签 c++ python boost-python

使用 boost::python,我已经能够包装一个具有一些虚函数的类 (Node),这一直很糟糕,但现在我'我试图覆盖类的 setattr/getattr。 我有 boost::python 来调用我自己的 setattr 实现,但我不知道如何避免发生递归。

所以我有一个 Node 类,我希望能够编写:

node1.param1 = 5          # Call node.SetParam
node1.plain_member = 7    # Call object.__setattr__

到目前为止,我已经(非常删节):

namespace bpy = boost::python;

struct NodeWrap : vcNode, bpy::wrapper<Node> {
  ...  
  static void setattr(bpy::object obj, std::string attr, bpy::object val)
  {
     NodeWrap const& node = bpy::extract<NodeWrap const&>(obj)();
     ParamRef p = node.FindParam(attr);
     if (p)
        py_to_param(p, val); //This part works fine
     else
     {
        obj.attr(attr) = val; //Problematic line - recurses indefinitely
     }
  }
};

然后在 BOOST_PYTHON_MODULE 部分,我有:

bpy::class_<NodeWrap, boost::shared_ptr<NodeWrap>, boost::noncopyable>("Node")
  ...
  .def("__setattr__". &NodeWrap::setattr);

正如我所说,它编译得很好,并且会正确设置任何节点“params”,但是如果我尝试设置一个非参数,例如 self.plain_old_member = 7 然后我得到“超出递归深度”错误,因为我收集到 boost::object::attr 将调用类的 __setattr__ 方法

在 python 中,我会通过使用来解决这个问题

super(Node).__setattr__(self, attr, val)

在问题行中,但我不知道如何从 boost::python 做到这一点。 如果必须的话,我不介意使用 C API(事实上,我已经尝试使用 PyObject_SetAttrString 但无济于事),但我只是不知道如何从这里到达那里。

干杯, 马特

最佳答案

我相信您需要的 Python C-API 函数是 PyObject_GenericSetAttr;也就是说,您应该将“有问题的行”替换为:

bpy::str attr_str(attr);
if (PyObject_GenericSetAttr(obj.ptr(), attr_str.ptr(), val.ptr()) != 0)
    bpy::throw_error_already_set();

我认为这相当于在 Python 中调用 object.__setattr__(self, attr, val),这与在基类上调用 __setattr__ 是不一样的,但仅当基类也覆盖 __setattr__ 时,差异才有意义。如果是这种情况,您需要执行以下操作:

bpy::object cls(bpy::handle<>(PyObject_Type(obj.ptr())));
bpy::object base_cls = cls.attr("__bases__")[0];
base_cls.attr("__setattr__")(obj, attr, val);

关于c++ - 如何在包装类(来自 C++)中覆盖 __setattr__?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10694367/

相关文章:

c++ - 简单的 OpenGL 纹理贴图不起作用?

c++ - 在 C++ 中计算二项式系数模块素数 p

C++ 编译器无法识别成员函数和类型

python - ttk.Separator 设置长/宽

c++ - Boost.Python 和 Boost.Signals2 : Segmentation faults

c++ - 确定 PyObject* 是否为 PyLongDoubleScalarObject (numpy)

c++ - 如何使此 jpeg 压缩更快

python - 有没有办法用 Python 原生解决方案替换 Django 的 smart_str?

python - 为什么向 subprocess.Popen 提供标准输入会导致写入标准输出的内容发生变化?

c++ - 公开类的 boost::tuple 部分以 boost python