1

我正在编写一些代码,它根据列索引从行中返回列值。该行在 C++ 中不时更新,我希望 python 代码保留对列值的引用。以下代码反映了我当前的解决方案,其中我必须重复获取列值。

struct Foo
{
   PyObject * get(int pos)
   {
       // Position 0 is an integer value.  Position 1 is a float value
       if (pos == 0)
           return Py_BuildValue ("i", m_int);
       else
           return Py_BuildValue ("f", m_float);
   }
   void set_int(int i)
   {
       m_int = i;
   }
   void set_float(float f)
   {
       m_float = f;
   }
   int m_int;
   float m_float;
};

我的绑定很简单:

class_<Foo> ("Foo")
        .def("get", &Foo::get)
        .def("set_int", &Foo::set_int)
        .def("set_float", &Foo::set_float)
        ;

这在 python 级别上工作,如下所示:

In [16]: foo = Foo()
In [17]: foo.set_int(1)
In [18]: foo.set_float(2.5)
In [19]: i = foo.get(0)
In [20]: f = foo.get(1)
In [21]: i
Out[21]: 1

In [22]: type(i)
Out[22]: int

In [23]: f
Out[23]: 2.5

In [24]: type(f)
Out[24]: float

到目前为止,一切都很好。但是,当我修改 foo 时,我希望 i 和 f 反映新值。目前,它们反映了旧值。

In [25]: foo.set_int(42)
In [26]: i
Out[26]: 1

如何设置 C++ 和绑定代码,以便“get”返回对 Foo 成员变量的引用而不是副本?

4

1 回答 1

2

您需要将整数值包装在对象类中。原语在 Python 中是不可变的,因此当您返回一个 int 值时,它永远不会引用原始 int,而只是一个 const 副本。您可以返回以下形式的新结构:

struct IntWrap {
     int *value;
     int get() { return *value; }
     void set_int(int nval) { *value = nval; }
     ...
};

class_<IntWrap > ("IntWrap")
     .def("get", &IntWrap::get)
     .set("set_int", &IntWrap::set_int)
     ...

并制作包装函数绑定,将结构视为 Python 中的可变整数。然而,这确实违反了 Python 中原语的 constness 习惯用法。

这是一篇关于从or有效继承的帖子,您可以在其中更改整数样式对象以使用 IntWrap 代替(以防您想要一些更像开箱即用的东西)。strintint

于 2013-04-24T16:50:09.757 回答