call.md
1> **Источник:** https://python-all.ru/3.12/c-api/call.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# Протокол вызова89CPython поддерживает два протокола вызова: *tp\_call* и vectorcall.1011## *tp\_call*1213Экземпляры классов, в которых задан [`tp_call`](https://python-all.ru/3.12/c-api/typeobj.html#c.PyTypeObject.tp_call), являются вызываемыми. Сигнатура слота:1415```c16PyObject *tp_call(PyObject *callable, PyObject *args, PyObject *kwargs);17```1819Вызов производится с использованием кортежа для позиционных аргументов и словаря для именованных аргументов, аналогично `callable(*args, **kwargs)` в коде Python. *args* должно быть не NULL (используйте пустой кортеж, если аргументов нет), но *kwargs* может быть *NULL*, если именованные аргументы отсутствуют.2021Это соглашение используется не только в *tp\_call*: [`tp_new`](https://python-all.ru/3.12/c-api/typeobj.html#c.PyTypeObject.tp_new) и [`tp_init`](https://python-all.ru/3.12/c-api/typeobj.html#c.PyTypeObject.tp_init) также передают аргументы таким образом.2223Для вызова объекта используйте [`PyObject_Call()`](https://python-all.ru/3.12/c-api/call.html#c.PyObject_Call) или другой [API вызова](https://python-all.ru/3.12/c-api/call.html#capi-call).2425## Протокол Vectorcall2627Добавлено в версии 3.9.2829Протокол vectorcall был представлен в [**PEP 590**](https://python-all.ru/3.12/c-api/call.html) как дополнительный протокол для повышения эффективности вызовов.3031Как правило, CPython предпочитает vectorcall для внутренних вызовов, если вызываемый объект его поддерживает. Однако это не жёсткое правило. Кроме того, некоторые сторонние расширения используют *tp\_call* напрямую (вместо [`PyObject_Call()`](https://python-all.ru/3.12/c-api/call.html#c.PyObject_Call)). Поэтому класс, поддерживающий vectorcall, должен также реализовывать [`tp_call`](https://python-all.ru/3.12/c-api/typeobj.html#c.PyTypeObject.tp_call). Более того, вызываемый объект должен вести себя одинаково независимо от используемого протокола. Рекомендуемый способ добиться этого – задать [`tp_call`](https://python-all.ru/3.12/c-api/typeobj.html#c.PyTypeObject.tp_call) равным [`PyVectorcall_Call()`](https://python-all.ru/3.12/c-api/call.html#c.PyVectorcall_Call). Это стоит повторить:3233> **Предупреждение**34>35> Класс, поддерживающий vectorcall, **должен** также реализовывать [`tp_call`](https://python-all.ru/3.12/c-api/typeobj.html#c.PyTypeObject.tp_call) с той же семантикой.3637Изменено в версии 3.12: Флаг [`Py_TPFLAGS_HAVE_VECTORCALL`](https://python-all.ru/3.12/c-api/typeobj.html#c.Py_TPFLAGS_HAVE_VECTORCALL) теперь удаляется из класса, когда метод [`__call__()`](https://python-all.ru/3.12/reference/datamodel.html#object.__call__) класса переопределяется. (При этом внутренне устанавливается только [`tp_call`](https://python-all.ru/3.12/c-api/typeobj.html#c.PyTypeObject.tp_call), что может привести к поведению, отличному от функции vectorcall). В более ранних версиях Python vectorcall следует использовать только с [`immutable`](https://python-all.ru/3.12/c-api/typeobj.html#c.Py_TPFLAGS_IMMUTABLETYPE) или статическими типами.3839Класс не должен реализовывать vectorcall, если это будет медленнее, чем *tp\_call*. Например, если вызываемая сторона всё равно должна преобразовывать аргументы в кортеж args и словарь kwargs, то нет смысла реализовывать vectorcall.4041Классы могут реализовать протокол vectorcall, установив флаг [`Py_TPFLAGS_HAVE_VECTORCALL`](https://python-all.ru/3.12/c-api/typeobj.html#c.Py_TPFLAGS_HAVE_VECTORCALL) и задав [`tp_vectorcall_offset`](https://python-all.ru/3.12/c-api/typeobj.html#c.PyTypeObject.tp_vectorcall_offset) в качестве смещения внутри структуры объекта, где находится *vectorcallfunc*. Это указатель на функцию со следующей сигнатурой:4243#### `typedef PyObject *(*vectorcallfunc)(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwnames)`4445*Часть [Stable ABI](https://python-all.ru/3.12/c-api/stable.html#stable) начиная с версии 3.12.*4647- *callable* – это вызываемый объект.48- ***args* – это массив C, состоящий из позиционных аргументов, за которыми следуют**4950 значения именованных аргументов. Может быть *NULL*, если аргументов нет.51- ***nargsf* – это количество позиционных аргументов плюс, возможно,**5253 флаг [`PY_VECTORCALL_ARGUMENTS_OFFSET`](https://python-all.ru/3.12/c-api/call.html#c.PY_VECTORCALL_ARGUMENTS_OFFSET). Чтобы получить фактическое количество позиционных аргументов из *nargsf*, используйте [`PyVectorcall_NARGS()`](https://python-all.ru/3.12/c-api/call.html#c.PyVectorcall_NARGS).54- ***kwnames* – это кортеж, содержащий имена именованных аргументов;**5556 другими словами, ключи словаря kwargs. Эти имена должны быть строками (экземплярами `str` или подкласса) и они должны быть уникальными. Если именованных аргументов нет, то *kwnames* может быть *NULL*.5758#### `PY_VECTORCALL_ARGUMENTS_OFFSET`5960*Часть [Stable ABI](https://python-all.ru/3.12/c-api/stable.html#stable) начиная с версии 3.12.*6162Если этот флаг установлен в аргументе vectorcall *nargsf*, вызываемой стороне разрешается временно изменить `args[-1]`. Иными словами, *args* указывает на аргумент 1 (а не 0) в выделенном векторе. Вызываемая сторона должна восстановить значение `args[-1]` перед возвратом.6364Для [`PyObject_VectorcallMethod()`](https://python-all.ru/3.12/c-api/call.html#c.PyObject_VectorcallMethod) этот флаг, напротив, означает, что `args[0]` может быть изменён.6566Если это можно сделать дёшево (без дополнительных выделений памяти), вызывающим сторонам рекомендуется использовать [`PY_VECTORCALL_ARGUMENTS_OFFSET`](https://python-all.ru/3.12/c-api/call.html#c.PY_VECTORCALL_ARGUMENTS_OFFSET). Это позволит таким вызываемым объектам, как связанные методы, выполнять последующие вызовы (которые включают добавленный аргумент *self*) очень эффективно.6768Добавлено в версии 3.8.6970Для вызова объекта, реализующего vectorcall, используйте функцию [call API](https://python-all.ru/3.12/c-api/call.html#capi-call), как и для любого другого вызываемого объекта. Обычно наиболее эффективным будет [`PyObject_Vectorcall()`](https://python-all.ru/3.12/c-api/call.html#c.PyObject_Vectorcall).7172> **Примечание**73>74> В CPython 3.8 API vectorcall и связанные функции были доступны временно под именами с ведущим подчеркиванием: `_PyObject_Vectorcall`, `_Py_TPFLAGS_HAVE_VECTORCALL`, `_PyObject_VectorcallMethod`, `_PyVectorcall_Function`, `_PyObject_CallOneArg`, `_PyObject_CallMethodNoArgs`, `_PyObject_CallMethodOneArg`. Кроме того, `PyObject_VectorcallDict` был доступен как `_PyObject_FastCallDict`. Старые имена по-прежнему определены как псевдонимы новых имен без подчеркивания.7576### Управление рекурсией7778При использовании *tp\_call* вызываемым сторонам не нужно беспокоиться о [рекурсии](https://python-all.ru/3.12/c-api/exceptions.html#recursion): CPython использует [`Py_EnterRecursiveCall()`](https://python-all.ru/3.12/c-api/exceptions.html#c.Py_EnterRecursiveCall) и [`Py_LeaveRecursiveCall()`](https://python-all.ru/3.12/c-api/exceptions.html#c.Py_LeaveRecursiveCall) для вызовов, выполненных с помощью *tp\_call*.7980Для эффективности это не относится к вызовам, выполненным с помощью vectorcall: вызываемая сторона должна использовать *Py\_EnterRecursiveCall* и *Py\_LeaveRecursiveCall*, если это необходимо.8182### API поддержки Vectorcall8384#### `Py_ssize_t PyVectorcall_NARGS(size_t nargsf)`8586*Часть [Stable ABI](https://python-all.ru/3.12/c-api/stable.html#stable) начиная с версии 3.12.*8788Получив аргумент vectorcall *nargsf*, возвращает фактическое количество аргументов. В настоящее время эквивалентно:8990```c91(Py_ssize_t)(nargsf & ~PY_VECTORCALL_ARGUMENTS_OFFSET)92```9394Однако следует использовать функцию `PyVectorcall_NARGS`, чтобы обеспечить возможность будущих расширений.9596Добавлено в версии 3.8.9798#### `vectorcallfunc PyVectorcall_Function(PyObject *op)`99100Если *op* не поддерживает протокол vectorcall (либо из-за того, что тип не поддерживает, либо конкретный экземпляр), возвращает *NULL*. В противном случае возвращает указатель на функцию vectorcall, сохранённый в *op*. Эта функция никогда не возбуждает исключения.101102Это в основном полезно для проверки, поддерживает ли *op* vectorcall, что можно сделать, проверив `PyVectorcall_Function(op) != NULL`.103104Добавлено в версии 3.9.105106#### `PyObject *PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *dict)`107108*Часть [Stable ABI](https://python-all.ru/3.12/c-api/stable.html#stable) начиная с версии 3.12.*109110Вызывает [`vectorcallfunc`](https://python-all.ru/3.12/c-api/call.html#c.vectorcallfunc) объекта *callable* с позиционными и именованными аргументами, заданными в виде кортежа и словаря соответственно.111112Это специализированная функция, предназначенная для размещения в слоте [`tp_call`](https://python-all.ru/3.12/c-api/typeobj.html#c.PyTypeObject.tp_call) или использования в реализации `tp_call`. Она не проверяет флаг [`Py_TPFLAGS_HAVE_VECTORCALL`](https://python-all.ru/3.12/c-api/typeobj.html#c.Py_TPFLAGS_HAVE_VECTORCALL) и не обращается к `tp_call` в качестве запасного варианта.113114Добавлено в версии 3.8.115116## API вызова объектов117118Доступны различные функции для вызова объекта Python. Каждая преобразует свои аргументы в соглашение, поддерживаемое вызываемым объектом – *tp\_call* или vectorcall. Чтобы выполнить как можно меньше преобразований, выбирайте ту, которая лучше всего подходит под формат имеющихся у вас данных.119120В следующей таблице приведены доступные функции; подробнее см. в документации для каждой из них.121122| Функция | вызываемый | аргументы | именованные аргументы |123| --- | --- | --- | --- |124| [`PyObject_Call()`](https://python-all.ru/3.12/c-api/call.html#c.PyObject_Call) | `PyObject *` | кортеж | словарь/`NULL` |125| [`PyObject_CallNoArgs()`](https://python-all.ru/3.12/c-api/call.html#c.PyObject_CallNoArgs) | `PyObject *` | – | – |126| [`PyObject_CallOneArg()`](https://python-all.ru/3.12/c-api/call.html#c.PyObject_CallOneArg) | `PyObject *` | 1 объект | – |127| [`PyObject_CallObject()`](https://python-all.ru/3.12/c-api/call.html#c.PyObject_CallObject) | `PyObject *` | кортеж/`NULL` | – |128| [`PyObject_CallFunction()`](https://python-all.ru/3.12/c-api/call.html#c.PyObject_CallFunction) | `PyObject *` | формат | – |129| [`PyObject_CallMethod()`](https://python-all.ru/3.12/c-api/call.html#c.PyObject_CallMethod) | объект + `char*` | формат | – |130| [`PyObject_CallFunctionObjArgs()`](https://python-all.ru/3.12/c-api/call.html#c.PyObject_CallFunctionObjArgs) | `PyObject *` | вариативный | – |131| [`PyObject_CallMethodObjArgs()`](https://python-all.ru/3.12/c-api/call.html#c.PyObject_CallMethodObjArgs) | объект + имя | вариативный | – |132| [`PyObject_CallMethodNoArgs()`](https://python-all.ru/3.12/c-api/call.html#c.PyObject_CallMethodNoArgs) | объект + имя | – | – |133| [`PyObject_CallMethodOneArg()`](https://python-all.ru/3.12/c-api/call.html#c.PyObject_CallMethodOneArg) | объект + имя | 1 объект | – |134| [`PyObject_Vectorcall()`](https://python-all.ru/3.12/c-api/call.html#c.PyObject_Vectorcall) | `PyObject *` | vectorcall | vectorcall |135| [`PyObject_VectorcallDict()`](https://python-all.ru/3.12/c-api/call.html#c.PyObject_VectorcallDict) | `PyObject *` | vectorcall | словарь/`NULL` |136| [`PyObject_VectorcallMethod()`](https://python-all.ru/3.12/c-api/call.html#c.PyObject_VectorcallMethod) | аргумент + имя | vectorcall | vectorcall |137138#### `PyObject *PyObject_Call(PyObject *callable, PyObject *args, PyObject *kwargs)`139140*Возвращаемое значение: новая ссылка.*141142*Часть [Stable ABI](https://python-all.ru/3.12/c-api/stable.html#stable).*143144Вызывает вызываемый объект Python *callable* с аргументами, заданными кортежем *args*, и именованными аргументами, заданными словарём *kwargs*.145146*args* не должен быть *NULL*; используйте пустой кортеж, если аргументы не нужны. Если именованные аргументы не нужны, *kwargs* может быть *NULL*.147148Возвращает результат вызова при успехе или возбуждает исключение и возвращает *NULL* при неудаче.149150Это эквивалент выражения Python: `callable(*args, **kwargs)`.151152#### `PyObject *PyObject_CallNoArgs(PyObject *callable)`153154*Возвращаемое значение: новая ссылка.*155156*Часть [Stable ABI](https://python-all.ru/3.12/c-api/stable.html#stable) начиная с версии 3.10.*157158Вызывает вызываемый объект Python *callable* без аргументов. Это самый эффективный способ вызова вызываемого объекта Python без аргументов.159160Возвращает результат вызова при успехе или возбуждает исключение и возвращает *NULL* при неудаче.161162Добавлено в версии 3.9.163164#### `PyObject *PyObject_CallOneArg(PyObject *callable, PyObject *arg)`165166*Возвращаемое значение: новая ссылка.*167168Вызывает вызываемый объект Python *callable* ровно с одним позиционным аргументом *arg* и без именованных аргументов.169170Возвращает результат вызова при успехе или возбуждает исключение и возвращает *NULL* при неудаче.171172Добавлено в версии 3.9.173174#### `PyObject *PyObject_CallObject(PyObject *callable, PyObject *args)`175176*Возвращаемое значение: новая ссылка.*177178*Часть [Stable ABI](https://python-all.ru/3.12/c-api/stable.html#stable).*179180Вызывает вызываемый объект Python *callable* с аргументами, заданными кортежем *args*. Если аргументы не нужны, *args* может быть *NULL*.181182Возвращает результат вызова при успехе или возбуждает исключение и возвращает *NULL* при неудаче.183184Это эквивалент выражения Python: `callable(*args)`.185186#### `PyObject *PyObject_CallFunction(PyObject *callable, const char *format, ...)`187188*Возвращаемое значение: новая ссылка.*189190*Часть [Stable ABI](https://python-all.ru/3.12/c-api/stable.html#stable).*191192Вызывает вызываемый объект Python *callable* с переменным числом аргументов C. Аргументы C описываются строкой формата в стиле [`Py_BuildValue()`](https://python-all.ru/3.12/c-api/arg.html#c.Py_BuildValue). Формат может быть *NULL*, что означает, что аргументы не предоставлены.193194Возвращает результат вызова при успехе или возбуждает исключение и возвращает *NULL* при неудаче.195196Это эквивалент выражения Python: `callable(*args)`.197198Обратите внимание, что если передавать только аргументы [PyObject](https://python-all.ru/3.12/c-api/structures.html#c.PyObject)\*, то [`PyObject_CallFunctionObjArgs()`](https://python-all.ru/3.12/c-api/call.html#c.PyObject_CallFunctionObjArgs) будет более быстрой альтернативой.199200Изменено в версии 3.4: Тип *format* был изменён с `char *`.201202#### `PyObject *PyObject_CallMethod(PyObject *obj, const char *name, const char *format, ...)`203204*Возвращаемое значение: новая ссылка.*205206*Часть [Stable ABI](https://python-all.ru/3.12/c-api/stable.html#stable).*207208Вызывает метод с именем *name* объекта *obj* с переменным числом аргументов C. Аргументы C описываются строкой формата [`Py_BuildValue()`](https://python-all.ru/3.12/c-api/arg.html#c.Py_BuildValue), которая должна порождать кортеж.209210Формат может быть *NULL*, что означает, что аргументы не предоставлены.211212Возвращает результат вызова при успехе или возбуждает исключение и возвращает *NULL* при неудаче.213214Это эквивалент выражения Python: `obj.name(arg1, arg2, ...)`.215216Обратите внимание, что если передавать только аргументы [PyObject](https://python-all.ru/3.12/c-api/structures.html#c.PyObject)\*, то [`PyObject_CallMethodObjArgs()`](https://python-all.ru/3.12/c-api/call.html#c.PyObject_CallMethodObjArgs) будет более быстрой альтернативой.217218Изменено в версии 3.4: Типы *name* и *format* были изменены с `char *`.219220#### `PyObject *PyObject_CallFunctionObjArgs(PyObject *callable, ...)`221222*Возвращаемое значение: новая ссылка.*223224*Часть [Stable ABI](https://python-all.ru/3.12/c-api/stable.html#stable).*225226Вызывает вызываемый объект Python *callable* с переменным числом аргументов [PyObject](https://python-all.ru/3.12/c-api/structures.html#c.PyObject)\*. Аргументы передаются как переменное число параметров, за которым следует *NULL*.227228Возвращает результат вызова при успехе или возбуждает исключение и возвращает *NULL* при неудаче.229230Это эквивалент выражения Python: `callable(arg1, arg2, ...)`.231232#### `PyObject *PyObject_CallMethodObjArgs(PyObject *obj, PyObject *name, ...)`233234*Возвращаемое значение: новая ссылка.*235236*Часть [Stable ABI](https://python-all.ru/3.12/c-api/stable.html#stable).*237238Вызывает метод объекта Python *obj*, где имя метода задаётся как строковый объект Python в *name*. Он вызывается с переменным числом аргументов [PyObject](https://python-all.ru/3.12/c-api/structures.html#c.PyObject)\*. Аргументы передаются как переменное число параметров, за которым следует *NULL*.239240Возвращает результат вызова при успехе или возбуждает исключение и возвращает *NULL* при неудаче.241242#### `PyObject *PyObject_CallMethodNoArgs(PyObject *obj, PyObject *name)`243244Вызывает метод объекта Python *obj* без аргументов, где имя метода задаётся как строковый объект Python в *name*.245246Возвращает результат вызова при успехе или возбуждает исключение и возвращает *NULL* при неудаче.247248Добавлено в версии 3.9.249250#### `PyObject *PyObject_CallMethodOneArg(PyObject *obj, PyObject *name, PyObject *arg)`251252Вызывает метод объекта Python *obj* с одним позиционным аргументом *arg*, где имя метода задаётся как строковый объект Python в *name*.253254Возвращает результат вызова при успехе или возбуждает исключение и возвращает *NULL* при неудаче.255256Добавлено в версии 3.9.257258#### `PyObject *PyObject_Vectorcall(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwnames)`259260*Часть [Stable ABI](https://python-all.ru/3.12/c-api/stable.html#stable) начиная с версии 3.12.*261262Вызывает вызываемый объект Python *callable*. Аргументы те же, что и для [`vectorcallfunc`](https://python-all.ru/3.12/c-api/call.html#c.vectorcallfunc). Если *callable* поддерживает [vectorcall](https://python-all.ru/3.12/c-api/call.html#vectorcall), то эта функция напрямую вызывает функцию vectorcall, хранящуюся в *callable*.263264Возвращает результат вызова при успехе или возбуждает исключение и возвращает *NULL* при неудаче.265266Добавлено в версии 3.9.267268#### `PyObject *PyObject_VectorcallDict(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwdict)`269270Вызывает *callable* с позиционными аргументами, передаваемыми точно так же, как в протоколе [vectorcall](https://python-all.ru/3.12/c-api/call.html#vectorcall), но с именованными аргументами, передаваемыми в виде словаря *kwdict*. Массив *args* содержит только позиционные аргументы.271272Независимо от того, какой протокол используется внутри, требуется выполнить преобразование аргументов. Поэтому эту функцию следует использовать только в том случае, если у вызывающего кода уже есть словарь, готовый для именованных аргументов, но нет кортежа для позиционных аргументов.273274Добавлено в версии 3.9.275276#### `PyObject *PyObject_VectorcallMethod(PyObject *name, PyObject *const *args, size_t nargsf, PyObject *kwnames)`277278*Часть [Stable ABI](https://python-all.ru/3.12/c-api/stable.html#stable) начиная с версии 3.12.*279280Вызывает метод, используя соглашение о вызове vectorcall. Имя метода задаётся в виде строки Python *name*. Объект, чей метод вызывается – это *args\[0\]*, а массив *args*, начиная с *args\[1\]*, представляет аргументы вызова. Должен присутствовать хотя бы один позиционный аргумент. *nargsf* – это количество позиционных аргументов, включая *args\[0\]*, плюс [`PY_VECTORCALL_ARGUMENTS_OFFSET`](https://python-all.ru/3.12/c-api/call.html#c.PY_VECTORCALL_ARGUMENTS_OFFSET), если значение `args[0]` может временно изменяться. Именованные аргументы можно передавать так же, как в [`PyObject_Vectorcall()`](https://python-all.ru/3.12/c-api/call.html#c.PyObject_Vectorcall).281282Если объект обладает возможностью [`Py_TPFLAGS_METHOD_DESCRIPTOR`](https://python-all.ru/3.12/c-api/typeobj.html#c.Py_TPFLAGS_METHOD_DESCRIPTOR), то будет вызван непривязанный объект метода с полным вектором *args* в качестве аргументов.283284Возвращает результат вызова при успехе или возбуждает исключение и возвращает *NULL* при неудаче.285286Добавлено в версии 3.9.287288## API поддержки вызова289290#### `int PyCallable_Check(PyObject *o)`291292*Часть [Stable ABI](https://python-all.ru/3.12/c-api/stable.html#stable).*293294Определяет, является ли объект *o* вызываемым. Возвращает `1`, если объект вызываем, и `0` в противном случае. Эта функция всегда завершается успешно.295