3

PyList_Appendを処理するときに、Py_DECREF/INCREFで迷子になります。誰かが次のコードについてコメントをすることができますか?

PyObject * bugmaybe(PyObject *self, PyObject *args)
{
   PyObject * trio=PyList_New(0);
   PyObject * trio_tmp;
   PyObject * otmp = PyFloat_FromDouble(1.2);
   PyList_Append(trio_tmp,otmp);
   //Py_DECREF(otmp);
   otmp = PyFloat_FromDouble(2.3);
   PyList_Append(trio_tmp,otmp);
   //Py_DECREF(otmp);
   PyList_Append(trio,trio_tmp);
   Py_INCREF(trio_tmp);
}
4

2 に答える 2

6

リストのサイズが事前にわかっている場合は、通常、適切なサイズでリストを作成して を使用する方が高速PyList_SetItem()です。

あなたのコードは単に間違っており、初期化されていませんtrio_tmp

これを試して:

PyObject * bugmaybe(PyObject *self, PyObject *args)
{
  PyObject * trio=PyList_New(3);
  PyObject * otmp = PyFloat_FromDouble(1.2);
  PyList_SetItem(trio,0,otmp);
  otmp = PyFloat_FromDouble(2.3);
  PyList_SetItem(trio,1,otmp);
  PyList_Append(trio,2, PyList_New(0));
  return trio;
}

本当に を使用したい場合PyList_Append、コードはほとんどtrio_tmp問題なく、最後に の初期化と余分な Py_INCREF が欠けているだけです。

PyObject * bugmaybe(PyObject *self, PyObject *args)
{
  PyObject * trio=PyList_New(0);
  // trio has refcount 1
  PyObject * trio_tmp = PyList_New(0);
  // trio_tmp has recount 1
  PyObject * otmp = PyFloat_FromDouble(1.2);
  // otmp has recount 1
  PyList_Append(trio_tmp,otmp);
  // Append does not steal a reference, so otmp refcoun = 2
  Py_DECREF(otmp);
  // otmp refcount = 1, but stored in the list so the pointer var
  // can be reused
  otmp = PyFloat_FromDouble(2.3);
  PyList_Append(trio_tmp,otmp);
  Py_DECREF(otmp);
  // as above
  PyList_Append(trio,trio_tmp);
  // decrement refcount for trio_tmp, as it has recount 2 now.
  Py_DECREF(trio_tmp);
  return trio;
}

上記のコードは次と同等です。

 trio = []
 trio_tmp = []
 otmp = 1.2
 trio_tmp.append(otmp)
 otmp = 2.3
 trio_tmp.append(otmp)
 trio.append(trio_tmp)

それが役に立てば幸い。主なヒントはドキュメントにあります。「参照を盗む」と表示されている場合、関数は基本的に所有権を取得します。「新しい参照」と表示されている場合は、INCREF を実行します。何も言われていない場合は、おそらく INCREF と DECREF のペアを実行します必要に応じて。

于 2012-06-02T15:58:54.810 に答える
1

PyList_Append()参照を「盗む」ことはありません。したがって、後で追加された値を使用しない場合は、参照を解除してください。

また、関数から a を返すことを忘れないでください。そうしないとPyObject*、システムは例外が発生したと見なします。

于 2012-06-02T15:58:22.673 に答える