Pregunta Py_INCREF / DECREF: Cuando


Es correcto decir lo siguiente:

  • Si se crea un objeto Python en una función C, pero la función no lo devuelve, no INCREF es necesario, pero una DECREF es.

  • [falso] Si la función lo devuelve, necesita INCREF, en la función que recibe el valor de retorno. [/ false]

  • Al asignar variables tipo C como atributos, como double, int etc., al objeto Python, no INCREF o DECREF es necesario.

  • Asignar objetos Python como atributos a otros objetos de Python es como sigue:

    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 forma segura en cada situación? (No me he encontrado con uno donde me haya causado problemas)

  • dealloc de un objeto de Python necesita DECREF para cada otro objeto de Python que tenga como atributo, pero no para los atributos que son tipos de C.

Editar

Con 'C tipo como atributo' quiero decir bar y baz:

typedef struct {
    PyObject_HEAD
    PyObject *foo;
    int bar;
    double baz;
} FooBarBaz;

32
2018-01-11 12:47


origen


Respuestas:


Primero, lea esto más cuidadosamente, específicamente el último párrafo, http://docs.python.org/extending/extending.html#ownership-rules

Una manera fácil de pensar es pensar en los recuentos de referencia.

  1. Tu primera declaración es correcta. Si crea un nuevo objeto Python (por ejemplo PyLong) entonces ya tiene un recuento de referencia de 1. Esto está bien si va a devolverlo, pero si no va a devolverlo, necesita ser recogido basura por Python y solo está marcado para GC con recuento = 0, por lo tanto, necesita DECREF si no va a devolverlo.

  2. La segunda declaración es falsa. Si necesita devolverlo y lo creó, simplemente devuélvalo. Devolución de la propiedad de las transferencias. Si tuviera que INCREF antes de regresar, le está diciendo a Python  también están reteniendo una copia. Entonces, de nuevo, si lo creas, refcount = 1. Si luego haces INCREF, refcount = 2. Pero esto es no lo que quiere, quiere volver con refcount = 1.

  3. no soy bastante Seguro que entiendo esto, pero esto es más una pregunta relacionada con C. ¿Cómo estás agregando un int o double a un objeto de Python?

  4. ¿Puedes dar un ejemplo donde ese método no funcionará?

  5. Nuevamente, no estoy seguro de cuándo un tipo C es un atributo de un objeto Python. Cada int, double, long, etc. está envuelto por un objeto Python de una 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 haber aclarado y no confundir más.


38
2018-01-11 15:22