Подтвердить что ты не робот

Что такое "правильный" способ передать логическое расширение Python C?

Это простой пример из документации python (http://docs.python.org/extending/extending.html):

static PyObject *
spam_system(PyObject *self, PyObject *args)
{
    const char *command;
    int sts;

    if (!PyArg_ParseTuple(args, "s", &command))
        return NULL;
    sts = system(command);
    return Py_BuildValue("i", sts);
}

Если я хочу передать дополнительный логический параметр функции - какой "правильный" способ сделать это?

Кажется, что нет опции bool для перехода к PyArg_ParseTuple(). Поэтому я подумал о следующем:

  • прочитайте целое число и просто используйте значение (поскольку bool является подклассом int)
  • вызов PyBool_FromLong() для целого числа
  • прочитать и объект и вызвать PyBool_Check(), чтобы убедиться, что это bool
  • возможно, есть способ получить любой тип переменной и получить ее значение истинности (т.е. пустой массив будет ложным и т.д.), что обычно делает функция python.

Любое из этих предпочтительных? Другие варианты?

4b9b3361

Ответ 1

4 возможно, есть способ получить любой тип переменной и получить ее значение истинности (т.е. пустой массив будет ложным и т.д.), что и есть питон функция обычно делаю.

Да: (из Справочник по API Python/C)

int PyObject_IsTrue(PyObject *o)

Возвращает 1, если объект o считается истинным, а 0 - иным. Это эквивалентно выражению Python, а не o. При сбое, return -1.

ИЗМЕНИТЬ. Чтобы ответить на фактический вопрос, я думаю, что подход 1 правильный, потому что int действительно соответствует типу C. Подход 4 хорош, но если вы задокументируете свою функцию как взятие bool, вы не обязаны принимать только любой объект. Явные проверки типов, как в 3 без причины, не одобряются в Python. Преобразование в другой объект Python, как в 2, не помогает вашему C-коду.

Ответ 2

В настоящее время синтаксический анализ целого числа (как "i") является принятым способом для bool.

Из Python 3.3, PyArg_ParseTuple примет "p" (для "предикат" ), за последние НОВОСТИ:

  • Проблема # 14705: семейство функций PyArg_Parse() теперь поддерживает формат "p" единица, которая принимает аргумент "boolean predicate". Он преобразует любой Python значение в целое число - 0, если оно "ложно", а 1 - в противном случае.

Обратите внимание, что при использовании PyArg_ParseTuple с "p" аргумент должен быть (указатель на) int, а не тип C99 bool:

int x;    // not "bool x"
PyArg_ParseTuple(args, kwds, "p", &x);

Ответ 3

Я нашел другой подход:

PyObject* py_expectArgs;
bool expectArgs;

PyArg_ParseTupleAndKeywords(args, keywds, (char *)"O!", (char **)kwlist, &PyBool_Type, &py_expectArgs);

expectArgs = PyObject_IsTrue(py_expectArgs);

В случае неправильного вызова параметра существует "авто" исключение. "Аргумент 1 должен быть bool, а не int"