Izz ad-Din Ruhulessin, 14.01.2011 17:52:
I am writing a Python C extension and I have some trouble understanding how
reference counting works exactly. Though I think I understand the practice
on simple operations (see my question at stackoverflow:
http://stackoverflow.com/questions/4657764/py-incref-decref-when), but on
more "complex" operations I cannot quite grasp it yet.

For example, in the following helper function, do I need to DECREF or are
all the references automatically destroyed when the function returns?

double Py_GetAttr_DoubleFromFloat(PyObject *obj, const char *attr)
{
if ((PyObject_GetAttrString(obj, attr) == False) ||
(PyObject_HasAttrString(obj, attr) == False)) {
return -9999.0;
}

This is C, nothing is done automatically. So you need to take care to properly DECREF the references. one or two references are leaked in the above.

BTW, what's "False"? Did you mean "Py_False"?


return PyFloat_AsDouble(PyNumber_Float(PyObject_GetAttrString(obj, attr)));

This leaks two references.


Please share your thoughts, thanks in advance, kind regards,

Consider taking a look at Cython. It's an extension language that lets you write Python code and generates C code for you. In Cython, your code above simply spells

    cdef double Py_GetAttr_DoubleFromFloat(obj, attr):
        value = getattr(obj, attr, False)
        if value is False:
            return -9999.0
        return value

Note that I'm using a Python object for 'attr' for performance reasons (and for Python 3 portability).

I would expect that the above is at least a bit faster than your code, but it handles ref-counting correctly.

Having said that, I'd frown a bit about an API that returns either False or a double value ...

Stefan

_______________________________________________
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Reply via email to