了解PyDict_Check行为

时间:2013-02-05 10:48:01

标签: python cpython

我一直在玩Python C API。我很喜欢它,但今天我遇到了障碍。我有一个Python扩展,它有一个函数,需要一个或两个字典作为参数。我担心我可能误解了PyDict_CheckPyArg_ParseTuple的工作原理。这是一个愚蠢的例子:

static PyObject * doStuffToOtherStuff(MyCustomPyObject *self, PyObject *args) {
  char const *fmt = "OO";
  PyObject dict1, dict2;

  if (!PyArg_ParseTuple(args, fmt, &dict1, &dict2))
    return NULL;

  int hasDict1 = PyDict_Check(&dict1);
  int hasDict2 = PyDict_Check(&dict2);

  printf("%d %d\n");

  Py_INCREF(Py_None);
  return Py_None;
}

构建和导入时,我将其称为:

myClass.doStuffToOtherStuff(dict(), None)

我希望这会打印 1 0 但实际上会打印 1 1 。那样做:     myClass.doStuffToOtherStuff(无,无)     myClass.doStuffToOtherStuff(无,dict())     myClass.doStuffToOtherStuff({},无)     #etc ...

如果我将PyDict_Check更改为PyDict_CheckExact,则无论我作为参数传递的是什么,都会打印0 0

非常感谢任何见解。

1 个答案:

答案 0 :(得分:1)

带有PyArg_ParseTuple参数的

O需要一个指向PyObject *的指针,而不是指向PyObject的指针(即,可变参数应该是PyObject **类型的指针)。

所以你的代码应该是:

  char const *fmt = "OO";
  PyObject *dict1, *dict2;

  if (!PyArg_ParseTuple(args, fmt, &dict1, &dict2))
    return NULL;

  int hasDict1 = PyDict_Check(dict1);
  int hasDict2 = PyDict_Check(dict2);

  // ...