如何使用PyArg_ParseTupleAndKeywords来解析带有可选参数和关键字的元组?

时间:2016-01-28 17:31:09

标签: python python-2.7 numpy

我到处寻找,但我找不到PyArg_ParseTupleAndKeywords()与元组一起使用的示例 - 包含可选参数 - 关键字。我找到的最接近的是this question,但答案并不是特别有帮助。大多数示例似乎都将关键字作为可选参数,但似乎元组也应该能够包含可选参数。

假设我试图解析以下参数:

  • numpy double of double(强制性)
  • numpy数组的双打(可选,无关键字)
  • 可选关键字参数:
    • k1 => numpy数组双打
    • k2 =>整数
    • k3 =>双
    • k4 => Python类实例

好像我应该做像

这样的事情
static PyObject* pymod_func(PyObject* self, PyObject* args, PyObject* kwargs) {
  static char* keywords[] = {"k1", "k2", "k3", "k4", NULL};

  PyObject *arg1, *arg2, *k1, *k4
  PyObject *arr1, *arr2, *karr1;
  double *k3;
  int *k2;
  PyArg_ParseTupleAndKeywords(args, kwargs, "O!|O!OidO", keywords, &arg1, &PyArray_Type, &arg2, &PyArray_Type, &k1, &PyArray_Type, &k2, &k3, &k4);

  arr1 = PyArray_FROM_OTF(arg1, NPY_FLOAT64, NPY_ARRAY_INOUT_ARRAY);
  if (arr1 == NULL) return NULL;

  arr2 = PyArray_FROM_OTF(arg1, NPY_FLOAT64, NPY_ARRAY_INOUT_ARRAY);
  // no null check, because optional

  karr1 = PyArray_FROM_OTF(k1, NPY_FLOAT64, NPY_ARRAY_INOUT_ARRAY);
  // again, no null check, because this is optional

  // do things with k3, k2, and k4 also

  return NULL;
}

我看过的其他地方,但没有找到太多帮助:

使用PyArg_ParseTupleAndKeywords()的适当方式是什么?

2 个答案:

答案 0 :(得分:2)

我认为类似于以下简化解决方案的内容应该适用于您的场景,但如果您有许多可选的args或更有趣的arg类型,它会变得很糟糕。 我不确定是否有更好的解决方案,但我还没找到。希望有一天会有人发布更清洁的解决方案。

您必须聪明才能生成有用的arg解析错误消息 在更复杂的解析方案中。

static PyObject* nasty_func(PyObject* self, PyObject* args, PyObject* kwargs) {
  static char* keywords[] = {"one", "optional", "two", NULL};
  static char* keywords_alt[] = {"one", "two", NULL};

  int ok = 0;
  PyObject *result = NULL;

  int *one;
  char *two;
  int *optional;

  ok = PyArg_ParseTupleAndKeywords(args, kwargs, "iis", keywords, &one, &optional, &two);

  if (!ok) {
    PyErr_Clear();
    ok = PyArg_ParseTupleAndKeywords(args, kwargs, "is", keywords_alt, &one, &two);
    if (!ok) {
      PyErr_SetString(PyExc_TypeError, "Invalid args. allowed formats: 'one:i, two:s' or 'one:i, optional:i, two:s'");
      return NULL;
    }
  }

  // do stuff with your parsed variables

  return result;
}

答案 1 :(得分:0)

从Python 3.3开始,您可以在indicate that the rest of the arguments are keyword-only的格式字符串中使用public void ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); .... // In production, the Angular files will be served from this directory services.AddSpaStaticFiles(configuration => { configuration.RootPath = "ClientApp/dist/ClientApp";//change here }); ... } ,从Python 3.6开始,可以在$中使用空名称,从you can indicate a positional-only parameter开始使用论点。

因此,在足够高的Python版本中,您可以使用类似以下的代码:

keywords