boost.python: modifying class getattr
Hello all, I'm trying to access the type structure for a c++ class exposed to Python using boost.python, so that I can have ob_type->tp_getattro point to a custom function instead of PyObject_GenericGetAttr (for those who wonder why, it's a performance issue: with my current project, PyObject_GenericGetAttr is always called first, fails to find the requested attribute, and then __getattr__ is called on the wrapped object, which returns the attribute. I get an extra PyString_FromFormatV for each access to an attribute value, and this slows down my code by ~20%) If I write: object Foo_ = class_<Foo>("Foo", init< >()) .def("__getattr__", &Foo::Foo_getattr) .def("__setattr__", &Foo::Foo_setattr) ..., is there a way to modify the type object associated with Foo_ instances so that instead of calling PyObject_GenericGetAttr when an attribute is requested, Python calls a function PyObject * Foo_GetAttr(PyObject *obj, PyObject *name) ? Thanks, Julien.
On Tuesday 15 November 2005 01:59, Julien Sylvestre wrote:
If I write: object Foo_ = class_<Foo>("Foo", init< >()) .def("__getattr__", &Foo::Foo_getattr) .def("__setattr__", &Foo::Foo_setattr) ...,
is there a way to modify the type object associated with Foo_ instances so that instead of calling PyObject_GenericGetAttr when an attribute is requested, Python calls a function PyObject *Foo_GetAttr(PyObject *obj, PyObject *name)
Ah, that would be cool; <dreaming>I would be looking for an analogous way to speed up __getitem__ making it comparable to that of a Python list..</dreaming> Ciao, / / /--/ / / ANS
Julien Sylvestre <jusylves@videotron.ca> writes:
Hello all, I'm trying to access the type structure for a c++ class exposed to Python using boost.python, so that I can have ob_type->tp_getattro point to a custom function instead of PyObject_GenericGetAttr (for those who wonder why, it's a performance issue: with my current project, PyObject_GenericGetAttr is always called first, fails to find the requested attribute, and then __getattr__ is called on the wrapped object, which returns the attribute. I get an extra PyString_FromFormatV for each access to an attribute value, and this slows down my code by ~20%)
If I write: object Foo_ = class_<Foo>("Foo", init< >()) .def("__getattr__", &Foo::Foo_getattr) .def("__setattr__", &Foo::Foo_setattr) ...,
is there a way to modify the type object associated with Foo_ instances so that instead of calling PyObject_GenericGetAttr when an attribute is requested, Python calls a function PyObject * Foo_GetAttr(PyObject *obj, PyObject *name) ?
PyTypeObject* Foo_t = (PyTypeObject*)Foo_.ptr(); Foo_t->tp_getattro = Foo_GetAttr; HTH, -- Dave Abrahams Boost Consulting www.boost-consulting.com
On Wednesday 16 November 2005 18:37, David Abrahams wrote:
is there a way to modify the type object associated with Foo_ instances so that instead of calling PyObject_GenericGetAttr when an attribute is requested, Python calls a function PyObject * Foo_GetAttr(PyObject *obj, PyObject *name) ?
PyTypeObject* Foo_t = (PyTypeObject*)Foo_.ptr(); Foo_t->tp_getattro = Foo_GetAttr;
Interesting. In a desperate attempt to make accessing (2-dimensional) point elements from my Polygon class faster (a native python list of these objects is twice as fast), I tried to manually set (PyTypeObject*)Foo_.ptr() ->tp_as_sequence->sq_item to my hand-crafted __getitem__ implementation... which made it *slower*. ;-) Obviously, my __getitem__ using extract<Vector2Array>(self)() is doing an extra type-checking which my previously used boost::python function did not do (since boost knew that self contained my object), and - I should have had a little more confidence in the power of boost::python - was already registered in the special tp_as_sequence->sq_item slot (which triggered an assert I had put in before overwriting sq_item). ;-} That's cool. What a pity that I spent my afternoon trying to optimize where it was already done optimally. ;-/ Obviously, the only remaining advantage of a python list is that it contains readily-wrapped python objects that can simply be returned (after an incref())?! -- Ciao, / / /--/ / / ANS
participants (4)
-
David Abrahams -
Hans Meine -
Hans Meine -
Julien Sylvestre