Py_INCREF/DECREF:何时

Izz*_*sin 36 python python-c-api

说明以下内容是正确的:

  • 如果在C函数中创建了Python对象,但该函数没有返回它,INCREF则不需要,但是a DECREF.

  • [false]如果函数确实返回了它,你需要INCREF在接收返回值的函数中.[/ false]

  • 当分配了C类型的变量作为属性,如double,int等等,给Python对象,没有INCREFDECREF需要.

  • 将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
    
    Run Code Online (Sandbox Code Playgroud)

编辑: - >我可以在任何情况下安全地使用它吗?(没有碰到一个导致我问题的地方)

  • Python对象的dealloc需要DECREF用于其作为属性的每个其他Python对象,但不适用于C类型的属性.

编辑

'C type as a attribute'是指bar和baz:

typedef struct {
    PyObject_HEAD
    PyObject *foo;
    int bar;
    double baz;
} FooBarBaz;
Run Code Online (Sandbox Code Playgroud)

mil*_*man 43

首先,请仔细阅读,特别是最后一段,http://docs.python.org/extending/extending.html#ownership-rules

思考它的简单方法是考虑引用计数.

  1. 你的第一个陈述是正确的.如果你创建一个新的Python对象(比如说PyLong),那么它的引用计数已经为1.如果你要返回它就没关系,但是如果你不打算返回它,那么它需要被Python垃圾收集并且它仅针对GC标记为refcount = 0,因此如果您不打算返回它,则需要DECREF.

  2. 第二个陈述是错误的.如果您需要返回并创建它,请返回它.返还转让所有权.如果你在返回之前是INCREF,那么你告诉Python 也保留了副本.所以再次,如果你创建它,refcount = 1.如果你然后做INCREF然后refcount = 2.但这不是你想要的,你想用refcount = 1返回.

  3. 不太确定我能得到这个,但这更多是与C相关的问题.你是如何添加一个intdouble一个Python对象的?

  4. 你能给出一个例子,该方法不起作用吗?

  5. 同样,我不确定C类型何时是Python对象的属性.每int,double,long等是通过以某种方式或另一种Python对象缠绕.

上面的链接概述了这些答案的警告.阅读之后你甚至不需要我的不良解释.我希望我澄清并且不要混淆.