2016-08-07 2 views
0

Я пытаюсь перевести a, b, c, d = iterable в C/API Python.Распаковка итерации в расширении Python

Я ищу функцию, похожую на PyArg_ParseTuple, только для итераций.

Другими словами, что-то в области PyIter_Parse или PyObject_ParseIterable, если бы такие функции существовали бы.

Любые советы по его реализации?

ответ

1

Нет, нет вспомогательной функции, которая может сделать это за вас.

Вам нужно будет использовать PyIter_Next() до max раз, чтобы получить значения, поднять исключение, если вы не можете получить как минимум min значений, а затем просто создайте кортеж из этого.

Что-то вроде (не проверялось, в основном воровал из PySequence_Tuple()):

int 
PyIter_LimitedTuple(PyObject *v, Py_ssize_t min, Py_ssize_t max) 
{ 
    PyObject *it; /* iter(v) */ 
    PyObject *result = NULL; 
    Py_ssize_t j; 

    it = PyObject_GetIter(v); 
    if (it == NULL) 
     return NULL; 

    /* allocate space. */ 
    result = PyTuple_New(max); 
    if (result == NULL) 
     goto Fail; 

    /* Fill the tuple. */ 
    for (j = 0; ; ++j) { 
     PyObject *item = PyIter_Next(it); 
     if (item == NULL) { 
      if (PyErr_Occurred()) 
       goto Fail; 
      break; 
     } 

     if (j > max) { 
      PyErr_Format(PyExc_ValueError, 
       "too many values to unpack"); 
      goto Fail; 
     } 

     PyTuple_SET_ITEM(result, j, item); 
    } 

    if (j < min) { 
     PyErr_Format(PyExc_ValueError, 
      "need more than %d value to unpack", 
      j); 
     goto Fail; 
    } 

    /* Cut tuple back if fewer than max items were available. */ 
    if (j < max && 
     _PyTuple_Resize(&result, j) != 0) 
     goto Fail; 

    Py_DECREF(it); 
    return result; 

Fail: 
    Py_XDECREF(result); 
    Py_DECREF(it); 
    return NULL; 
} 

затем передать результирующий кортеж PyArg_UnpackTuple().

+0

До этого я справлялся. Хотя я сначала использовал 'iterator = PyObject_GetIter (iterable)'. То, что я надеялся, хотя (я только что исправил свой вопрос), должен получить что-то большее, чем 'PyArg_PargeTuple' для любого итеративного, а не только кортежей. –

+0

@JessieK: Обновлено; просто создайте кортеж из итерируемого, но в пределах установленных пределов, затем используйте 'PyArg_UnpackTuple()' из этого. –

Смежные вопросы