|
Boost : |
From: Donavon Keithley (keithley_at_[hidden])
Date: 2001-05-04 17:02:00
I'm experimenting with a binary tree structure using polymorphic nodes, but
I seem to be losing object identity on the Python side.
struct BaseNode
{
BaseNode* l;
BaseNode* r;
};
struct DerivedNode : public BaseNode
{
int foo;
};
Following the cookbook, I wrap BaseNode* as follows:
PyObject* to_python(BaseNode* p)
{
return
python::python_extension_class_converters<BaseNode>::smart_ptr_to_python(p);
}
PyObject* to_python(const BaseNode* p)
{
return to_python(const_cast<BaseNode*>(p));
}
Similarly for DerivedNode. And then build the classes like so:
boost::python::class_builder<BaseNode> BaseNode_class(this_module,
"BaseNode");
BaseNode_class.def(boost::python::constructor<>());
BaseNode_class.def_read_write(&BaseNode::l, "l");
BaseNode_class.def_read_write(&BaseNode::r, "r");
boost::python::class_builder<DerivedNode> DerivedNode_class(this_module,
"DerivedNode");
DerivedNode_class.def(boost::python::constructor<>());
DerivedNode_class.def_read_write(&DerivedNode::foo, "foo");
DerivedNode_class.declare_base(BaseNode_class, python::without_downcast);
In Python:
>>> dn0 = DerivedNode()
>>> dn0.foo = 0
>>> dn1 = DerivedNode()
>>> dn1.foo = 1
>>> dn0.l = dn1
>>> dn0.l
<BaseNode object at 00D46540> <-- Uh oh...
>>> dn0.l.foo
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: foo
This clearly doesn't work, so my question is what would be a correct
approach?
I've noticed -- and this is probably related -- that if I instantiate
BaseNodes, it sort of works:
>>> bn0 = BaseNode()
>>> bn1 = BaseNode()
>>> bn0.l = bn1
I've verified that bn0.l and bn1 refer to the same instance of BaseNode on
the C++ side, in spite of the fact that their Python identities are not the
same:
>>> id(bn0.l)
13919552
>>> id(bn1)
13920016
I only barely understand how BPL works under the hood, but it seems that
what I need here is proxies on the Python side -- that is, a to_python
conversion that always returns the same PyObject for the same BaseNode* or
DerivedNode*.
Any insight would be greatly appreciated!
--Donavon
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk