[C++-sig] how to override __setattr__ of an extension class

Holger Joukl Holger.Joukl at LBBW.de
Tue Feb 28 14:17:47 CET 2012


> > To actually write to my instance dict I currently do
> >
> >      PyObject* __dict__ = PyObject_GetAttrString(m_self,
const_cast<char*>
> > ("__dict__"));
> >      PyDict_SetItemString(__dict__, name, value.ptr());
> >
> > inside MyExtensionClass::setattr (where m_self is PyObj*)
> >
> > Is there a better way?
> >
>
> Everything I can think of (e.g. extract the base class from __bases__[0]
> and call its setattr) is functionally equivalent and not any prettier.

Good to know. I'll stick to this, then.

> The trick is to do:
>
> bp::dict bp_dict = bp::extract<bp::dict>(__dict__);
> bp_dict[name] = value;
>
> Just calling the bp::dict invokes Python's dict constructor, which does
> a copy.

...and now that you've told me what to do I've found that it's actually
documented
here:

http://www.boost.org/doc/libs/1_48_0/libs/python/doc/tutorial/doc/html/python/object.html#python.extracting_c___objects:

"[...]
The astute reader might have noticed that the extract<T> facility in fact
solves the mutable copying problem:


dict d = extract<dict>(x.attr("__dict__"));
d["whatever"] = 3;          // modifies x.__dict__ !
[...]"


and there:



http://www.boost.org/doc/libs/1_48_0/libs/python/doc/v2/extract.html:
"[...] Because invoking a mutable python type with an argument of the same
type (e.g. list([1,2]) typically makes a copy of the argument object, this
may be the only way to access the ObjectWrapper's interface on the original
object.[...]"

Maybe that's only me but I don't think the info that gets you going here is
very obvious in the docs, more like
a casual side note. So for now I've added some info on this here:
http://wiki.python.org/moin/boost.python/extract

Many thanks
Holger

Landesbank Baden-Wuerttemberg
Anstalt des oeffentlichen Rechts
Hauptsitze: Stuttgart, Karlsruhe, Mannheim, Mainz
HRA 12704
Amtsgericht Stuttgart



More information about the Cplusplus-sig mailing list