
On 10/08/2011 04:54 PM, "Martin v. Löwis" wrote:
tmp = PyObject_CallMethod(result, "update", "O", other);
would be replaced with
PyObject *tmp; Py_identifier(update); ... tmp = PyObject_CallMethodId(result,&PyId_update, "O", other);
An alternative I am fond of is to to avoid introducing a new type, and simply initialize a PyObject * and register its address. For example: PyObject *tmp; static PyObject *s_update; // pick a naming convention PY_IDENTIFIER_INIT(update); tmp = PyObject_CallMethodObj(result, s_update, "O", other); (but also PyObject_GetAttr(o, s_update), etc.) PY_IDENTIFIER_INIT(update) might expand to something like: if (!s_update) { s_update = PyUnicode_InternFromString("update"); _Py_IdentifierAdd(&s_update); } _PyIdentifierAdd adds the address of the variable to a global set of C variables that need to be decreffed and zeroed-out at interpreted shutdown. The benefits of this approach is: * you don't need special "identifier" versions of functions such as PyObject_CallMethod. In my example I invented a PyObject_CallMethodObj, but adding that might be useful anyway. * a lot of Python/C code implements similar caching, often leaking strings. Hrvoje