42

陈述以下内容是否正确:

  1. 如果在 C 函数中创建了 Python 对象,但该函数没有返回它,则 noINCREF是必需的,但 aDECREF是。

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

  3. 将 C 类型变量作为属性(如doubleint)分配给 Python 对象时,不需要INCREFor DECREF

  4. 以下内容可以安全使用吗?将 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
    
  5. Python 对象的释放需要DECREF对其作为属性的所有其他 Python 对象进行,但对于 C 类型的属性则不需要。


编辑:

关于“C 类型作为属性”,我的意思是 bar 和 baz:

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

1 回答 1

48

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

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

  1. 你的第一个陈述是正确的。如果您创建一个新的 Python 对象(例如PyLong),那么它的引用计数已经为 1。如果您要返回它,这很好,但如果您不打算返回它,则它需要由 Python 进行垃圾收集并且它仅标记为 refcount=0 的 GC,因此如果您不打算返回它,则需要 DECREF。

  2. 第二个说法是错误的。如果您需要退回它并且您创建了它,只需退回它。归还转让所有权。如果您在返回之前要 INCREF,那么您就是在告诉 Python还保留了一份副本。同样,如果您创建它,则 refcount=1。如果您随后执行 INCREF,则 refcount=2。但这不是你想要的,你想用 refcount=1 返回。

  3. 不太确定我明白了,但这更像是一个与 C 相关的问题。你如何向 Python 对象添加int或?double

  4. 你能举个例子说明这种方法不起作用吗?

  5. 同样,我不确定 C 类型何时是 Python 对象的属性。每个int, double,long等都以某种方式被 Python 对象包装。

上面的链接中概述了这些答案的注意事项。看完之后你真的不应该需要我糟糕的解释。我希望我澄清并且没有混淆更多。

于 2011-01-11T15:22:45.330 回答