Es una correcta en afirmar lo siguiente:
Si se crea un objeto de Python en una función C, pero la función no lo devuelve, no se necesita INCREF
, pero sí una DECREF
.
[falso] Si la función lo devuelve, es necesario INCREF
, en la función que recibe el valor de retorno. [/ falso]
Al asignar variables de tipo C como atributos, como double
, int
etc., al objeto de Python, no se necesita INCREF
ni DECREF
.
Asignar objetos de Python como atributos a tus otros objetos de Python es así:
PyObject *foo; foo = bar // A Python object tmp = self->foo; Py_INCREF(foo); self->foo = foo; Py_XDECREF(tmp); //taken from the manual, but it is unclear if this works in every situation
EDITAR: -> ¿Puedo usar esto de manera segura en cada situación? (No me he topado con uno donde me causó problemas)
DECREF
para todos los demás objetos Python que tiene como atributo, pero no para los atributos que son de tipo C Editar
Con ‘tipo C como atributo’ me refiero a bar y baz:
typedef struct { PyObject_HEAD PyObject *foo; int bar; double baz; } FooBarBaz;
Primero, lea esto con más cuidado, específicamente el último párrafo, http://docs.python.org/extending/extending.html#ownership-rules
Una forma fácil de pensar es pensar en los recuentos de referencia.
Su primera statement es correcta. Si crea un nuevo objeto Python (por ejemplo, PyLong
), entonces ya tiene un número de referencia de 1. Esto está bien si lo va a devolver, pero si no lo va a devolver, debe ser recolectado por la basura. Python y solo está marcado para GC con refcount = 0, por lo tanto, debe DECRETARSE si no lo va a devolver.
La segunda afirmación es falsa. Si necesita devolverlo y lo ha creado, simplemente devuélvalo. Devolución de transferencias de titularidad. Si INCREFÍAS antes de regresar, entonces le estás diciendo a Python que también estás reteniendo una copia. Así que de nuevo, si lo creas, refcount = 1. Si luego haces INCREF entonces refcount = 2. Pero esto no es lo que quiere, quiere regresar con refcount = 1.
No estoy seguro de haberlo entendido, pero se trata más bien de una pregunta relacionada con C. ¿Cómo estás agregando un int
o un double
a un objeto de Python?
¿Puedes dar un ejemplo donde ese método no funcione?
De nuevo, no estoy seguro de cuándo un tipo C es un atributo de un objeto de Python. Cada int
, double
, long
, etc. está envuelto por un objeto Python de alguna manera u otra.
Las advertencias a estas respuestas se describen en el enlace de arriba. Realmente no deberías necesitar mi pobre explicación después de leer eso. Espero haberlo aclarado y no confundir más.