call.md
1> **Источник:** https://python-all.ru/3.13/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.13/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.13/c-api/typeobj.html#c.PyTypeObject.tp_new) и [`tp_init`](https://python-all.ru/3.13/c-api/typeobj.html#c.PyTypeObject.tp_init) также передают аргументы таким образом.2223Для вызова объекта используйте [`PyObject_Call()`](https://python-all.ru/3.13/c-api/call.html#c.PyObject_Call) или другой [API вызова](https://python-all.ru/3.13/c-api/call.html#capi-call).2425## Протокол Vectorcall2627Добавлено в версии 3.9.2829Протокол vectorcall был представлен в [**PEP 590**](https://python-all.ru/3.13/c-api/call.html) как дополнительный протокол для повышения эффективности вызовов.3031Как правило, CPython предпочитает vectorcall для внутренних вызовов, если вызываемый объект его поддерживает. Однако это не жёсткое правило. Кроме того, некоторые сторонние расширения используют *tp\_call* напрямую (вместо [`PyObject_Call()`](https://python-all.ru/3.13/c-api/call.html#c.PyObject_Call)). Поэтому класс, поддерживающий vectorcall, должен также реализовывать [`tp_call`](https://python-all.ru/3.13/c-api/typeobj.html#c.PyTypeObject.tp_call). Более того, вызываемый объект должен вести себя одинаково независимо от используемого протокола. Рекомендуемый способ добиться этого – задать `tp_call` равным [`PyVectorcall_Call()`](https://python-all.ru/3.13/c-api/call.html#c.PyVectorcall_Call). Это стоит повторить:3233> **Предупреждение**34>35> Класс, поддерживающий vectorcall, **должен** также реализовывать [`tp_call`](https://python-all.ru/3.13/c-api/typeobj.html#c.PyTypeObject.tp_call) с той же семантикой.3637Изменено в версии 3.12: Флаг [`Py_TPFLAGS_HAVE_VECTORCALL`](https://python-all.ru/3.13/c-api/typeobj.html#c.Py_TPFLAGS_HAVE_VECTORCALL) теперь удаляется из класса, когда метод [`__call__()`](https://python-all.ru/3.13/reference/datamodel.html#object.__call__) класса переопределяется. (При этом внутренне устанавливается только [`tp_call`](https://python-all.ru/3.13/c-api/typeobj.html#c.PyTypeObject.tp_call), что может привести к поведению, отличному от функции vectorcall). В более ранних версиях Python vectorcall следует использовать только с [`immutable`](https://python-all.ru/3.13/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.13/c-api/typeobj.html#c.Py_TPFLAGS_HAVE_VECTORCALL) и задав [`tp_vectorcall_offset`](https://python-all.ru/3.13/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.13/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.13/c-api/call.html#c.PY_VECTORCALL_ARGUMENTS_OFFSET). Чтобы получить фактическое количество позиционных аргументов из *nargsf*, используйте [`PyVectorcall_NARGS()`](https://python-all.ru/3.13/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.13/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.13/c-api/call.html#c.PyObject_VectorcallMethod) этот флаг, напротив, означает, что `args[0]` может быть изменён.6566Если это можно сделать дёшево (без дополнительных выделений памяти), вызывающим сторонам рекомендуется использовать [`PY_VECTORCALL_ARGUMENTS_OFFSET`](https://python-all.ru/3.13/c-api/call.html#c.PY_VECTORCALL_ARGUMENTS_OFFSET). Это позволит таким вызываемым объектам, как связанные методы, выполнять последующие вызовы (которые включают добавленный аргумент *self*) очень эффективно.6768Добавлено в версии 3.8.6970Для вызова объекта, реализующего vectorcall, используйте функцию [call API](https://python-all.ru/3.13/c-api/call.html#capi-call), как и для любого другого вызываемого объекта. Обычно наиболее эффективным будет [`PyObject_Vectorcall()`](https://python-all.ru/3.13/c-api/call.html#c.PyObject_Vectorcall).7172### Управление рекурсией7374При использовании *tp\_call* вызываемым сторонам не нужно беспокоиться о [рекурсии](https://python-all.ru/3.13/c-api/exceptions.html#recursion): CPython использует [`Py_EnterRecursiveCall()`](https://python-all.ru/3.13/c-api/exceptions.html#c.Py_EnterRecursiveCall) и [`Py_LeaveRecursiveCall()`](https://python-all.ru/3.13/c-api/exceptions.html#c.Py_LeaveRecursiveCall) для вызовов, выполненных с помощью *tp\_call*.7576Для эффективности это не относится к вызовам, выполненным с помощью vectorcall: вызываемая сторона должна использовать *Py\_EnterRecursiveCall* и *Py\_LeaveRecursiveCall*, если это необходимо.7778### API поддержки Vectorcall7980#### `Py_ssize_t PyVectorcall_NARGS(size_t nargsf)`8182*Часть [Stable ABI](https://python-all.ru/3.13/c-api/stable.html#stable) начиная с версии 3.12.*8384Получив аргумент vectorcall *nargsf*, возвращает фактическое количество аргументов. В настоящее время эквивалентно:8586```c87(Py_ssize_t)(nargsf & ~PY_VECTORCALL_ARGUMENTS_OFFSET)88```8990Однако следует использовать функцию `PyVectorcall_NARGS`, чтобы обеспечить возможность будущих расширений.9192Добавлено в версии 3.8.9394#### `vectorcallfunc PyVectorcall_Function(PyObject *op)`9596Если *op* не поддерживает протокол vectorcall (либо из-за того, что тип не поддерживает, либо конкретный экземпляр), возвращает *NULL*. В противном случае возвращает указатель на функцию vectorcall, сохранённый в *op*. Эта функция никогда не возбуждает исключения.9798Это в основном полезно для проверки, поддерживает ли *op* vectorcall, что можно сделать, проверив `PyVectorcall_Function(op) != NULL`.99100Добавлено в версии 3.9.101102#### `PyObject *PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *dict)`103104*Часть [Stable ABI](https://python-all.ru/3.13/c-api/stable.html#stable) начиная с версии 3.12.*105106Вызывает [`vectorcallfunc`](https://python-all.ru/3.13/c-api/call.html#c.vectorcallfunc) объекта *callable* с позиционными и именованными аргументами, заданными в виде кортежа и словаря соответственно.107108Это специализированная функция, предназначенная для размещения в слоте [`tp_call`](https://python-all.ru/3.13/c-api/typeobj.html#c.PyTypeObject.tp_call) или использования в реализации `tp_call`. Она не проверяет флаг [`Py_TPFLAGS_HAVE_VECTORCALL`](https://python-all.ru/3.13/c-api/typeobj.html#c.Py_TPFLAGS_HAVE_VECTORCALL) и не обращается к `tp_call` в качестве запасного варианта.109110Добавлено в версии 3.8.111112## API вызова объектов113114Доступны различные функции для вызова объекта Python. Каждая преобразует свои аргументы в соглашение, поддерживаемое вызываемым объектом – *tp\_call* или vectorcall. Чтобы выполнить как можно меньше преобразований, выбирайте ту, которая лучше всего подходит под формат имеющихся у вас данных.115116В следующей таблице приведены доступные функции; подробнее см. в документации для каждой из них.117118| Функция | вызываемый | аргументы | именованные аргументы |119| --- | --- | --- | --- |120| [`PyObject_Call()`](https://python-all.ru/3.13/c-api/call.html#c.PyObject_Call) | `PyObject *` | кортеж | словарь/`NULL` |121| [`PyObject_CallNoArgs()`](https://python-all.ru/3.13/c-api/call.html#c.PyObject_CallNoArgs) | `PyObject *` | – | – |122| [`PyObject_CallOneArg()`](https://python-all.ru/3.13/c-api/call.html#c.PyObject_CallOneArg) | `PyObject *` | 1 объект | – |123| [`PyObject_CallObject()`](https://python-all.ru/3.13/c-api/call.html#c.PyObject_CallObject) | `PyObject *` | кортеж/`NULL` | – |124| [`PyObject_CallFunction()`](https://python-all.ru/3.13/c-api/call.html#c.PyObject_CallFunction) | `PyObject *` | формат | – |125| [`PyObject_CallMethod()`](https://python-all.ru/3.13/c-api/call.html#c.PyObject_CallMethod) | объект + `char*` | формат | – |126| [`PyObject_CallFunctionObjArgs()`](https://python-all.ru/3.13/c-api/call.html#c.PyObject_CallFunctionObjArgs) | `PyObject *` | вариативный | – |127| [`PyObject_CallMethodObjArgs()`](https://python-all.ru/3.13/c-api/call.html#c.PyObject_CallMethodObjArgs) | объект + имя | вариативный | – |128| [`PyObject_CallMethodNoArgs()`](https://python-all.ru/3.13/c-api/call.html#c.PyObject_CallMethodNoArgs) | объект + имя | – | – |129| [`PyObject_CallMethodOneArg()`](https://python-all.ru/3.13/c-api/call.html#c.PyObject_CallMethodOneArg) | объект + имя | 1 объект | – |130| [`PyObject_Vectorcall()`](https://python-all.ru/3.13/c-api/call.html#c.PyObject_Vectorcall) | `PyObject *` | vectorcall | vectorcall |131| [`PyObject_VectorcallDict()`](https://python-all.ru/3.13/c-api/call.html#c.PyObject_VectorcallDict) | `PyObject *` | vectorcall | словарь/`NULL` |132| [`PyObject_VectorcallMethod()`](https://python-all.ru/3.13/c-api/call.html#c.PyObject_VectorcallMethod) | аргумент + имя | vectorcall | vectorcall |133134#### `PyObject *PyObject_Call(PyObject *callable, PyObject *args, PyObject *kwargs)`135136*Возвращаемое значение: новая ссылка.*137138*Часть [Stable ABI](https://python-all.ru/3.13/c-api/stable.html#stable).*139140Вызывает вызываемый объект Python *callable* с аргументами, заданными кортежем *args*, и именованными аргументами, заданными словарём *kwargs*.141142*args* не должен быть *NULL*; используйте пустой кортеж, если аргументы не нужны. Если именованные аргументы не нужны, *kwargs* может быть *NULL*.143144Возвращает результат вызова при успехе или возбуждает исключение и возвращает *NULL* при неудаче.145146Это эквивалент выражения Python: `callable(*args, **kwargs)`.147148#### `PyObject *PyObject_CallNoArgs(PyObject *callable)`149150*Возвращаемое значение: новая ссылка.*151152*Часть [Stable ABI](https://python-all.ru/3.13/c-api/stable.html#stable) начиная с версии 3.10.*153154Вызывает вызываемый объект Python *callable* без аргументов. Это самый эффективный способ вызова вызываемого объекта Python без аргументов.155156Возвращает результат вызова при успехе или возбуждает исключение и возвращает *NULL* при неудаче.157158Добавлено в версии 3.9.159160#### `PyObject *PyObject_CallOneArg(PyObject *callable, PyObject *arg)`161162*Возвращаемое значение: новая ссылка.*163164Вызывает вызываемый объект Python *callable* ровно с одним позиционным аргументом *arg* и без именованных аргументов.165166Возвращает результат вызова при успехе или возбуждает исключение и возвращает *NULL* при неудаче.167168Добавлено в версии 3.9.169170#### `PyObject *PyObject_CallObject(PyObject *callable, PyObject *args)`171172*Возвращаемое значение: новая ссылка.*173174*Часть [Stable ABI](https://python-all.ru/3.13/c-api/stable.html#stable).*175176Вызывает вызываемый объект Python *callable* с аргументами, заданными кортежем *args*. Если аргументы не нужны, *args* может быть *NULL*.177178Возвращает результат вызова при успехе или возбуждает исключение и возвращает *NULL* при неудаче.179180Это эквивалент выражения Python: `callable(*args)`.181182#### `PyObject *PyObject_CallFunction(PyObject *callable, const char *format, ...)`183184*Возвращаемое значение: новая ссылка.*185186*Часть [Stable ABI](https://python-all.ru/3.13/c-api/stable.html#stable).*187188Вызывает вызываемый объект Python *callable* с переменным числом аргументов C. Аргументы C описываются строкой формата в стиле [`Py_BuildValue()`](https://python-all.ru/3.13/c-api/arg.html#c.Py_BuildValue). Формат может быть *NULL*, что означает, что аргументы не предоставлены.189190Возвращает результат вызова при успехе или возбуждает исключение и возвращает *NULL* при неудаче.191192Это эквивалент выражения Python: `callable(*args)`.193194Обратите внимание, что если передавать только аргументы [PyObject](https://python-all.ru/3.13/c-api/structures.html#c.PyObject)\*, то [`PyObject_CallFunctionObjArgs()`](https://python-all.ru/3.13/c-api/call.html#c.PyObject_CallFunctionObjArgs) будет более быстрой альтернативой.195196Изменено в версии 3.4: Тип *format* был изменён с `char *`.197198#### `PyObject *PyObject_CallMethod(PyObject *obj, const char *name, const char *format, ...)`199200*Возвращаемое значение: новая ссылка.*201202*Часть [Stable ABI](https://python-all.ru/3.13/c-api/stable.html#stable).*203204Вызывает метод с именем *name* объекта *obj* с переменным числом аргументов C. Аргументы C описываются строкой формата [`Py_BuildValue()`](https://python-all.ru/3.13/c-api/arg.html#c.Py_BuildValue), которая должна порождать кортеж.205206Формат может быть *NULL*, что означает, что аргументы не предоставлены.207208Возвращает результат вызова при успехе или возбуждает исключение и возвращает *NULL* при неудаче.209210Это эквивалент выражения Python: `obj.name(arg1, arg2, ...)`.211212Обратите внимание, что если передавать только аргументы [PyObject](https://python-all.ru/3.13/c-api/structures.html#c.PyObject)\*, то [`PyObject_CallMethodObjArgs()`](https://python-all.ru/3.13/c-api/call.html#c.PyObject_CallMethodObjArgs) будет более быстрой альтернативой.213214Изменено в версии 3.4: Типы *name* и *format* были изменены с `char *`.215216#### `PyObject *PyObject_CallFunctionObjArgs(PyObject *callable, ...)`217218*Возвращаемое значение: новая ссылка.*219220*Часть [Stable ABI](https://python-all.ru/3.13/c-api/stable.html#stable).*221222Вызывает вызываемый объект Python *callable* с переменным числом аргументов [PyObject](https://python-all.ru/3.13/c-api/structures.html#c.PyObject)\*. Аргументы передаются как переменное число параметров, за которым следует *NULL*.223224Возвращает результат вызова при успехе или возбуждает исключение и возвращает *NULL* при неудаче.225226Это эквивалент выражения Python: `callable(arg1, arg2, ...)`.227228#### `PyObject *PyObject_CallMethodObjArgs(PyObject *obj, PyObject *name, ...)`229230*Возвращаемое значение: новая ссылка.*231232*Часть [Stable ABI](https://python-all.ru/3.13/c-api/stable.html#stable).*233234Вызывает метод объекта Python *obj*, где имя метода задаётся как строковый объект Python в *name*. Он вызывается с переменным числом аргументов [PyObject](https://python-all.ru/3.13/c-api/structures.html#c.PyObject)\*. Аргументы передаются как переменное число параметров, за которым следует *NULL*.235236Возвращает результат вызова при успехе или возбуждает исключение и возвращает *NULL* при неудаче.237238#### `PyObject *PyObject_CallMethodNoArgs(PyObject *obj, PyObject *name)`239240Вызывает метод объекта Python *obj* без аргументов, где имя метода задаётся как строковый объект Python в *name*.241242Возвращает результат вызова при успехе или возбуждает исключение и возвращает *NULL* при неудаче.243244Добавлено в версии 3.9.245246#### `PyObject *PyObject_CallMethodOneArg(PyObject *obj, PyObject *name, PyObject *arg)`247248Вызывает метод объекта Python *obj* с одним позиционным аргументом *arg*, где имя метода задаётся как строковый объект Python в *name*.249250Возвращает результат вызова при успехе или возбуждает исключение и возвращает *NULL* при неудаче.251252Добавлено в версии 3.9.253254#### `PyObject *PyObject_Vectorcall(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwnames)`255256*Часть [Stable ABI](https://python-all.ru/3.13/c-api/stable.html#stable) начиная с версии 3.12.*257258Вызывает вызываемый объект Python *callable*. Аргументы те же, что и для [`vectorcallfunc`](https://python-all.ru/3.13/c-api/call.html#c.vectorcallfunc). Если *callable* поддерживает [vectorcall](https://python-all.ru/3.13/c-api/call.html#vectorcall), то эта функция напрямую вызывает функцию vectorcall, хранящуюся в *callable*.259260Возвращает результат вызова при успехе или возбуждает исключение и возвращает *NULL* при неудаче.261262Добавлено в версии 3.8: как `_PyObject_Vectorcall`263264Изменено в версии 3.9: Переименовано в текущее имя без ведущего подчёркивания. Старое временное имя [мягко устарело](https://python-all.ru/3.13/glossary.html#term-soft-deprecated).265266#### `PyObject *PyObject_VectorcallDict(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwdict)`267268Вызывает *callable* с позиционными аргументами, передаваемыми точно так же, как в протоколе [vectorcall](https://python-all.ru/3.13/c-api/call.html#vectorcall), но с именованными аргументами, передаваемыми в виде словаря *kwdict*. Массив *args* содержит только позиционные аргументы.269270Независимо от того, какой протокол используется внутри, требуется выполнить преобразование аргументов. Поэтому эту функцию следует использовать только в том случае, если у вызывающего кода уже есть словарь, готовый для именованных аргументов, но нет кортежа для позиционных аргументов.271272Добавлено в версии 3.9.273274#### `PyObject *PyObject_VectorcallMethod(PyObject *name, PyObject *const *args, size_t nargsf, PyObject *kwnames)`275276*Часть [Stable ABI](https://python-all.ru/3.13/c-api/stable.html#stable) начиная с версии 3.12.*277278Вызывает метод, используя соглашение о вызове vectorcall. Имя метода задаётся в виде строки Python *name*. Объект, чей метод вызывается – это *args\[0\]*, а массив *args*, начиная с *args\[1\]*, представляет аргументы вызова. Должен присутствовать хотя бы один позиционный аргумент. *nargsf* – это количество позиционных аргументов, включая *args\[0\]*, плюс [`PY_VECTORCALL_ARGUMENTS_OFFSET`](https://python-all.ru/3.13/c-api/call.html#c.PY_VECTORCALL_ARGUMENTS_OFFSET), если значение `args[0]` может временно изменяться. Именованные аргументы можно передавать так же, как в [`PyObject_Vectorcall()`](https://python-all.ru/3.13/c-api/call.html#c.PyObject_Vectorcall).279280Если объект обладает возможностью [`Py_TPFLAGS_METHOD_DESCRIPTOR`](https://python-all.ru/3.13/c-api/typeobj.html#c.Py_TPFLAGS_METHOD_DESCRIPTOR), то будет вызван непривязанный объект метода с полным вектором *args* в качестве аргументов.281282Возвращает результат вызова при успехе или возбуждает исключение и возвращает *NULL* при неудаче.283284Добавлено в версии 3.9.285286## API поддержки вызова287288#### `int PyCallable_Check(PyObject *o)`289290*Часть [Stable ABI](https://python-all.ru/3.13/c-api/stable.html#stable).*291292Определяет, является ли объект *o* вызываемым. Возвращает `1`, если объект вызываем, и `0` в противном случае. Эта функция всегда завершается успешно.293