Python C API: PyEval_CallFunction? - PullRequest
       2

Python C API: PyEval_CallFunction?

5 голосов
/ 07 февраля 2011

Я обнаружил в Python C API функцию с именем PyEval_CallFunction, которая кажется полезной.Это позволяет вам вызывать вызываемый Python, говоря что-то вроде:

PyEval_CallFunction(obj, "OOO", a, b, c);

Однако я не могу найти официальную документацию по этой функции.Поиск Google выдает различные неофициальные учебные пособия , в которых обсуждается эта функция, но:

  1. Функция не задокументирована в официальных документах по Python, поэтому я не знаю, является ли это частью общедоступного API.

  2. Поиск в Интернете приводит к противоречивым политикам использования.В некоторых руководствах указывается, что строка формата должна содержать круглые скобки вокруг списка типов, например "(OiiO)", тогда как в других случаях я вижу, что она используется без круглых скобок.Когда я на самом деле пытаюсь использовать функцию в реальной программе, мне кажется, что требуется скобка, иначе она вызывает ошибку.

Я бы хотел использовать эту функцию, потому что она удобна.Кто-нибудь знает что-нибудь об этом, или знает, почему это не задокументировано ?Является ли это частью общедоступного API?

Ответы [ 2 ]

5 голосов
/ 08 февраля 2011

Причина, по которой это не задокументировано, заключается в том, что вы должны использовать PyObject_CallFunction .

Семейство функций PyEval_* - это необработанные внутренние вызовы для цикла оценки интерпретатора. Соответствующие документированные вызовы PyObject_* включают все дополнительные проверки целостности состояния интерпретатора, проверку аргументов и защиту стека.

5 голосов
/ 07 февраля 2011

Я также не смог найти много ссылок на него, но учебник, на который вы ссылались, упоминает это:

Формат строки и следующий аргументы такие же, как для Py_BuildValue (ХХХ, так что я действительно должен был описать что к настоящему времени!). Вызов, такой как

PyEval_CallFunction(obj, "iii", a, b, c);

эквивалентно

PyEval_CallObject(obj, Py_BuildValue("iii", a, b, c));

Полагаю, PyEval_CallFunction не является публичным API, так как его значение кажется довольно ограниченным. Между этими двумя нет большой разницы. Но опять же, я не особо занимаюсь расширениями Python, так что это мой взгляд на это.

PyEval_CallObject сам по себе является просто макросом вокруг PyEval_CallObjectWithKeywords.

#define PyEval_CallObject(func,arg) \
        PyEval_CallObjectWithKeywords(func, arg, (PyObject *)NULL)

По вопросу "Что такое публичный API?" Вот недавнее сообщение от Мартина против Лёвиса:

Просто чтобы подчеркнуть и поддержать Георгия объяснение: API не определен через документацию, но вместо прежде всего через заголовочные файлы. Все функции объявлены как PyAPI_FUNC и не начиная с _Py являются публичными API. Раньше было много недокументированного API (до 1.4, документации по API вообще не было, только учебник по модулю расширения); В наши дни все больше и больше API документируется.

http://mail.python.org/pipermail/python-dev/2011-February/107973.html

...