Подтвердить что ты не робот

Py_INCREF/DECREF: Когда

Правильно ли указывается следующее:

  • Если объект Python создается в C-функции, но функция не возвращает его, не требуется INCREF, но <DECREF.

  • [false] Если функция возвращает его, вам нужно INCREF в функции, которая получает возвращаемое значение. [/false]

  • При назначении C типизированных переменных в качестве атрибутов, таких как double, int и т.д., для объекта Python, не требуется INCREF или DECREF.

  • Назначение объектов Python в качестве атрибутов для других объектов Python выглядит следующим образом:

    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
    

EDIT: → Можно ли безопасно использовать это в любой ситуации? (не сталкивались с ситуацией, когда это вызывало у меня проблемы)

  • Dealloc объекта Python должен DECREF для каждого другого объекта Python, который он имеет в качестве атрибута, но не для атрибутов типа C.

Edit

С "C-типом как атрибутом" я имею в виду bar и baz:

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

Ответ 1

Прежде всего, прочитайте это более внимательно, особенно последний абзац, http://docs.python.org/extending/extending.html#ownership-rules

Легкий способ думать об этом - это думать о подсчетах ссылок.

  • Ваше первое утверждение верно. Если вы создаете новый объект Python (скажем PyLong), то у него уже есть счетчик ссылок 1. Это нормально, если вы собираетесь его вернуть, но если вы не собираетесь его возвращать, он должен быть мусором собранный Python, и он помечен только для GC с refcount = 0, поэтому вам нужно DECREF, если вы не собираетесь его возвращать.

  • Второе утверждение ложно. Если вам нужно вернуть его, и вы его создали, просто верните его. Возврат права собственности. Если вы вернулись к INCREF перед возвратом, то вы говорите Python, что вы также сохраняете копию. Итак, если вы создали его, refcount = 1. Если вы затем выполните INCREF, то refcount = 2. Но это не то, что вы хотите, вы хотите вернуться с refcount = 1.

  • Я не совсем уверен, что получаю это, но это скорее вопрос, связанный с C. Как вы добавляете int или double к объекту Python?

  • Можете ли вы привести пример, где этот метод не будет работать?

  • Опять же, я не уверен, когда тип C является атрибутом объекта Python. Каждый int, double, long и т.д. Каким-то образом обертывается объектом Python.

Оговорки к этим ответам изложены в ссылке выше. После этого вы действительно не должны нуждаться в моем плохом объяснении. Надеюсь, я разъяснил и больше не путаю.