42

次のように述べるのは正しいですか:

  1. PythonオブジェクトがC関数で作成されたが、関数がそれを返さない場合、必要はありませんINCREFが、は必要DECREFです。

  2. [false]関数がそれを返す場合は、戻り値を受け取る関数で、する必要がありINCREFます。[/ false]

  3. C型変数をPythonオブジェクトなどの属性として割り当てる場合、doubleまたはは必要ありません。intINCREFDECREF

  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. 2番目のステートメントは誤りです。返品する必要があり、作成した場合は、返品してください。返還は所有権を譲渡します。戻る前にINCREFを実行した場合は、コピーも保持していることをPythonに通知していることになります。繰り返しになりますが、作成する場合は、refcount=1です。その後、INCREFを実行すると、refcount=2になります。しかし、これはあなたが望むものではありません、あなたはrefcount=1で戻りたいです。

  3. これがわかるかどうかはわかりません、これはC関連の質問です。intまたはdoubleをPythonオブジェクトにどのように追加しますか?

  4. その方法が機能しない例を挙げていただけますか?

  5. 繰り返しますが、CタイプがPythonオブジェクトの属性であるかどうかはわかりません。すべてintdouble、、、longなどは、何らかの方法でPythonオブジェクトによってラップされます。

これらの回答に対する警告は、上記のリンクに概説されています。それを読んだ後、あなたは本当に私の貧弱な説明さえ必要とすべきではありません。明確にして、これ以上混乱しないことを願っています。

于 2011-01-11T15:22:45.330 に答える