[C++-sig] how to override __setattr__ of an extension class
Wojciech Mamrak
wmamrak at gmail.com
Tue Feb 28 15:35:26 CET 2012
Here is a part of my message posted here few months ago, which has
been left without any response (no offence - maybe it disappeared
somewhere):
The docs regarding the mutable copying problem are very misleading.
Following Python [1] and Boost [2] scripts do not produce the same results:
[1]
b = a = []
c = list(a)
a.append("s1")
print a.count("s1"), b.count("s1"), c.count("s1") #prints 1 1 0
[2]
list a, b, c;
b = a;
c = list(a);
a.append("s1");
list d = extract<list>(a);
printf("%i %i %i %i\n", a.count("s1"), b.count("s1"), c.count("s1"),
d.count("s1")); //prints 1 1 1 1
In [2] expected was 1 1 0 1 according to Pythonic behaviour (it states
in docs that such behaviour is mimicked). This is in conflict with
example provided in the tutorial.
regards
2012/2/28 Holger Joukl <Holger.Joukl at lbbw.de>:
>> > 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
>
> _______________________________________________
> Cplusplus-sig mailing list
> Cplusplus-sig at python.org
> http://mail.python.org/mailman/listinfo/cplusplus-sig
More information about the Cplusplus-sig
mailing list