Вы не должны использовать эти функции для построения структур данных динамического размера. В FAQ говорится, что PyTuple_Pack следует использовать вместо Py_BuildValue для кортежа произвольного размера, но это тоже неправильно; Я не знаю, почему это так говорит. PyTuple_Pack имеет те же проблемы с varargs, что и Py_BuildValue.
Чтобы построить кортеж переменной длины из C, используйте PyTuple_New
, чтобы создать неинициализированный кортеж желаемой длины, затем зациклите индексы и установите элементы с помощью PyTuple_SET_ITEM
. Да, это мутирует кортеж. PyTuple_SET_ITEM
является только безопасным для использования для инициализации свежих кортежей, которые еще не подвергались воздействию другого кода. Также имейте в виду, что PyTuple_SET_ITEM
крадет ссылку на новый элемент.
Например, чтобы построить кортеж из целых чисел от 0 до n-1:
PyObject *tup = PyTuple_New(n);
for (int i = 0; i < n; i++) {
// Note that PyTuple_SET_ITEM steals the reference we get from PyLong_FromLong.
PyTuple_SET_ITEM(tup, i, PyLong_FromLong(i));
}
Чтобы создать список переменной длины из C, вы можете сделать то же самое с помощью PyList_New
и PyList_SET_ITEM
, или вы можете создать пустой список с помощью PyList_New(0)
и добавлять элементы с помощью PyList_Append
, так же, как вы будет использовать []
и append
в Python, если у вас нет списочного понимания или умножения последовательности.