Anropsprotokoll¶
CPython stöder två olika anropsprotokoll: tp_call och vectorcall.
Protokollet tp_call¶
Instanser av klasser som sätter tp_call
är anropsbara. Signaturen för denna slot är:
PyObject *tp_call(PyObject *callable, PyObject *args, PyObject *kwargs);
Ett anrop görs med hjälp av en tuple för de positionella argumenten och en dict för nyckelordsargumenten, på samma sätt som callable(*args, **kwargs)
i Python-kod. args måste vara icke-NULL (använd en tom tupel om det inte finns några argument) men kwargs kan vara NULL om det inte finns några nyckelordsargument.
Denna konvention används inte bara av tp_call: tp_new
och tp_init
skickar också argument på detta sätt.
För att anropa ett objekt använder du PyObject_Call()
eller en annan call API.
Vectorcall-protokollet¶
Tillagd i version 3.9.
Protokollet vectorcall introducerades i PEP 590 som ett tilläggsprotokoll för att göra anrop mer effektiva.
Som tumregel kommer CPython att föredra vectorcall för interna anrop om den anropbara funktionen stöder det. Detta är dock inte en hård regel. Dessutom använder vissa tredjepartstillägg tp_call direkt (snarare än att använda PyObject_Call()
). Därför måste en klass som stöder vectorcall också implementera tp_call
. Dessutom måste den anropbara funktionen bete sig likadant oavsett vilket protokoll som används. Det rekommenderade sättet att uppnå detta är att sätta tp_call
till PyVectorcall_Call()
. Detta tål att upprepas:
Varning
En klass som stöder vectorcall måste också implementera tp_call
med samma semantik.
Ändrad i version 3.12: Flaggan Py_TPFLAGS_HAVE_VECTORCALL
tas nu bort från en klass när klassens metod __call__()
tilldelas på nytt. (Detta sätter internt tp_call
endast, och kan därmed få den att bete sig annorlunda än vectorcall-funktionen) I tidigare Python-versioner bör vectorcall endast användas med immutable
eller statiska typer.
En klass bör inte implementera vectorcall om det skulle vara långsammare än tp_call. Om den som ringer till exempel ändå måste konvertera argumenten till en args-tupel och kwargs-dict, finns det ingen anledning att implementera vectorcall.
Klasser kan implementera vectorcall-protokollet genom att aktivera flaggan Py_TPFLAGS_HAVE_VECTORCALL
och sätta tp_vectorcall_offset
till den offset i objektstrukturen där en vectorcallfunc visas. Detta är en pekare till en funktion med följande signatur:
-
typedef PyObject *(*vectorcallfunc)(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwnames)¶
- En del av Stabil ABI sedan version 3.12.
callable är det objekt som anropas.
- args är en C-matris som består av de positionella argumenten följt av
värden för nyckelordets argument. Detta kan vara NULL om det inte finns några argument.
- nargsf är antalet positionella argument plus eventuellt
PY_VECTORCALL_ARGUMENTS_OFFSET
flagga. För att få det faktiska antalet positionella argument från nargsf, användPyVectorcall_NARGS()
.
- kwnames är en tupel som innehåller namnen på nyckelordsargumenten;
med andra ord, nycklarna i kwargs-diktatet. Dessa namn måste vara strängar (instanser av
str
eller en underklass) och de måste vara unika. Om det inte finns några nyckelordsargument kan kwnames i stället vara NULL.
-
PY_VECTORCALL_ARGUMENTS_OFFSET¶
- En del av Stabil ABI sedan version 3.12.
Om denna flagga är satt i ett vectorcall nargsf-argument, tillåts den som ringer att tillfälligt ändra
args[-1]
. Med andra ord pekar args på argument 1 (inte 0) i den allokerade vektorn. Den anropade måste återställa värdet påargs[-1]
innan den returnerar.För
PyObject_VectorcallMethod()
betyder denna flagga istället attargs[0]
kan ändras.När de kan göra det billigt (utan ytterligare allokering), uppmuntras anropare att använda
PY_VECTORCALL_ARGUMENTS_OFFSET
. Detta gör det möjligt för anropbara objekt som bundna metoder att göra sina vidare anrop (som inkluderar ett föranslutet self-argument) mycket effektivt.Tillagd i version 3.8.
För att anropa ett objekt som implementerar vectorcall, använd en call API-funktion som med alla andra anropbara. PyObject_Vectorcall()
kommer vanligtvis att vara mest effektivt.
Kontroll av rekursion¶
När tp_call används behöver anropare inte oroa sig för recursion: CPython använder Py_EnterRecursiveCall()
och Py_LeaveRecursiveCall()
för anrop som görs med tp_call.
Av effektivitetsskäl är detta inte fallet för anrop som görs med vectorcall: den anropande parten bör använda Py_EnterRecursiveCall och Py_LeaveRecursiveCall vid behov.
API för Vectorcall-stöd¶
-
Py_ssize_t PyVectorcall_NARGS(size_t nargsf)¶
- En del av Stabil ABI sedan version 3.12.
Givet ett vectorcall nargsf-argument, returnerar det faktiska antalet argument. För närvarande likvärdig med:
(Py_ssize_t)(nargsf & ~PY_VECTORCALL_ARGUMENTS_OFFSET)
Funktionen
PyVectorcall_NARGS
bör dock användas för att möjliggöra framtida tillägg.Tillagd i version 3.8.
-
vectorcallfunc PyVectorcall_Function(PyObject *op)¶
Om op inte stöder vectorcall-protokollet (antingen för att typen inte gör det eller för att den specifika instansen inte gör det), returneras NULL. I annat fall returneras pekaren för vectorcall-funktionen som lagrats i op. Denna funktion ger aldrig upphov till ett undantag.
Detta är mest användbart för att kontrollera om op stöder vectorcall eller inte, vilket kan göras genom att kontrollera
PyVectorcall_Function(op) != NULL
.Tillagd i version 3.9.
-
PyObject *PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *dict)¶
- En del av Stabil ABI sedan version 3.12.
Anropa callable:s
vectorcallfunc
med positions- och nyckelordsargument som anges i en tuple respektive dict.Detta är en specialiserad funktion, avsedd att placeras i
tp_call
slot eller användas i en implementation avtp_call
. Den kontrollerar intePy_TPFLAGS_HAVE_VECTORCALL
flaggan och den faller inte tillbaka tilltp_call
.Tillagd i version 3.8.
API för objektanrop¶
Olika funktioner finns tillgängliga för att anropa ett Python-objekt. Varje funktion konverterar sina argument till en konvention som stöds av det anropade objektet - antingen tp_call eller vectorcall. För att göra så lite konvertering som möjligt, välj den som bäst passar det dataformat du har tillgängligt.
I följande tabell sammanfattas de tillgängliga funktionerna; för mer information, se respektive dokumentation.
Funktion |
anropsbar |
args |
kwargs |
---|---|---|---|
|
tupel |
dict/ |
|
|
— |
— |
|
|
1 objekt |
— |
|
|
tuple/ |
— |
|
|
format |
— |
|
obj + |
format |
— |
|
|
variadisk |
— |
|
obj + namn |
variadisk |
— |
|
obj + namn |
— |
— |
|
obj + namn |
1 objekt |
— |
|
|
vektoranrop |
vektoranrop |
|
|
vektoranrop |
dict/ |
|
arg + namn |
vektoranrop |
vektoranrop |
-
PyObject *PyObject_Call(PyObject *callable, PyObject *args, PyObject *kwargs)¶
- Returnera värde: Ny referens. En del av Stabil ABI.
Anropa ett anropbart Python-objekt callable, med argument som anges av tupeln args och namngivna argument som anges av ordlistan kwargs.
args får inte vara NULL; använd en tom tupel om inga argument behövs. Om inga namngivna argument behövs kan kwargs vara NULL.
Returnera resultatet av anropet om det lyckas, eller skapa ett undantag och returnera NULL om det misslyckas.
Detta är motsvarigheten till Python-uttrycket:
callable(*args, **kwargs)
.
-
PyObject *PyObject_CallNoArgs(PyObject *callable)¶
- Returnera värde: Ny referens. En del av Stabil ABI sedan version 3.10.
Anropa ett anropsbart Python-objekt callable utan några argument. Det är det mest effektiva sättet att anropa ett anropbart Python-objekt utan argument.
Returnera resultatet av anropet om det lyckas, eller skapa ett undantag och returnera NULL om det misslyckas.
Tillagd i version 3.9.
-
PyObject *PyObject_CallOneArg(PyObject *callable, PyObject *arg)¶
- Returnera värde: Ny referens.
Anropa ett anropbart Python-objekt callable med exakt 1 positionellt argument arg och inga nyckelordsargument.
Returnera resultatet av anropet om det lyckas, eller skapa ett undantag och returnera NULL om det misslyckas.
Tillagd i version 3.9.
-
PyObject *PyObject_CallObject(PyObject *callable, PyObject *args)¶
- Returnera värde: Ny referens. En del av Stabil ABI.
Anropar ett anropbart Python-objekt callable, med argument som ges av tupeln args. Om inga argument behövs kan args vara NULL.
Returnera resultatet av anropet om det lyckas, eller skapa ett undantag och returnera NULL om det misslyckas.
Detta är motsvarigheten till Python-uttrycket:
callable(*args)
.
-
PyObject *PyObject_CallFunction(PyObject *callable, const char *format, ...)¶
- Returnera värde: Ny referens. En del av Stabil ABI.
Anropar ett anropsbart Python-objekt callable, med ett variabelt antal C-argument. C-argumenten beskrivs med hjälp av en formatsträng av typen
Py_BuildValue()
. Formatet kan vara NULL, vilket indikerar att inga argument tillhandahålls.Returnera resultatet av anropet om det lyckas, eller skapa ett undantag och returnera NULL om det misslyckas.
Detta är motsvarigheten till Python-uttrycket:
callable(*args)
.Observera att om du bara skickar PyObject* args, är
PyObject_CallFunctionObjArgs()
ett snabbare alternativ.Ändrad i version 3.4: Typen av format ändrades från
char *
.
-
PyObject *PyObject_CallMethod(PyObject *obj, const char *name, const char *format, ...)¶
- Returnera värde: Ny referens. En del av Stabil ABI.
Anropa metoden med namnet name för objektet obj med ett variabelt antal C-argument. C-argumenten beskrivs av en
Py_BuildValue()
-formatsträng som ska producera en tupel.Formatet kan vara NULL, vilket indikerar att inga argument anges.
Returnera resultatet av anropet om det lyckas, eller skapa ett undantag och returnera NULL om det misslyckas.
Detta är motsvarigheten till Python-uttrycket:
obj.name(arg1, arg2, ...)
.Observera att om du bara skickar PyObject* args, är
PyObject_CallMethodObjArgs()
ett snabbare alternativ.Ändrad i version 3.4: Typerna name och format ändrades från
char *
.
-
PyObject *PyObject_CallFunctionObjArgs(PyObject *callable, ...)¶
- Returnera värde: Ny referens. En del av Stabil ABI.
Anropar ett anropbart Python-objekt callable, med ett variabelt antal PyObject*-argument. Argumenten tillhandahålls som ett variabelt antal parametrar följt av NULL.
Returnera resultatet av anropet om det lyckas, eller skapa ett undantag och returnera NULL om det misslyckas.
Detta är motsvarigheten till Python-uttrycket:
callable(arg1, arg2, ...)
.
-
PyObject *PyObject_CallMethodObjArgs(PyObject *obj, PyObject *name, ...)¶
- Returnera värde: Ny referens. En del av Stabil ABI.
Anropar en metod för Python-objektet obj, där namnet på metoden anges som ett Python-strängobjekt i name. Den anropas med ett variabelt antal PyObject*-argument. Argumenten ges som ett variabelt antal parametrar följt av NULL.
Returnera resultatet av anropet om det lyckas, eller skapa ett undantag och returnera NULL om det misslyckas.
-
PyObject *PyObject_CallMethodNoArgs(PyObject *obj, PyObject *name)¶
Anropa en metod för Python-objektet obj utan argument, där namnet på metoden anges som ett Python-strängobjekt i name.
Returnera resultatet av anropet om det lyckas, eller skapa ett undantag och returnera NULL om det misslyckas.
Tillagd i version 3.9.
-
PyObject *PyObject_CallMethodOneArg(PyObject *obj, PyObject *name, PyObject *arg)¶
Anropa en metod för Python-objektet obj med ett enda positionellt argument arg, där namnet på metoden anges som ett Python-strängobjekt i name.
Returnera resultatet av anropet om det lyckas, eller skapa ett undantag och returnera NULL om det misslyckas.
Tillagd i version 3.9.
-
PyObject *PyObject_Vectorcall(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwnames)¶
- En del av Stabil ABI sedan version 3.12.
Anropar ett anropsbart Python-objekt callable. Argumenten är desamma som för
vectorcallfunc
. Om callable stöder vectorcall, anropas direkt vectorcall-funktionen som finns lagrad i callable.Returnera resultatet av anropet om det lyckas, eller skapa ett undantag och returnera NULL om det misslyckas.
Tillagd i version 3.9.
-
PyObject *PyObject_VectorcallDict(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwdict)¶
Anropa callable med positionella argument som skickas exakt som i vectorcall-protokollet, men med nyckelordsargument som skickas som en ordbok kwdict. Arrayen args innehåller endast de positionella argumenten.
Oavsett vilket protokoll som används internt måste en konvertering av argumenten göras. Därför bör denna funktion endast användas om anroparen redan har en ordbok som är klar att användas för nyckelordsargumenten, men inte en tupel för positionsargumenten.
Tillagd i version 3.9.
-
PyObject *PyObject_VectorcallMethod(PyObject *name, PyObject *const *args, size_t nargsf, PyObject *kwnames)¶
- En del av Stabil ABI sedan version 3.12.
Anropar en metod med hjälp av anropskonventionen vectorcall. Namnet på metoden anges som en Python-sträng name. Objektet vars metod anropas är args[0], och args-arrayen som börjar på args[1] representerar argumenten för anropet. Det måste finnas minst ett positionellt argument. nargsf är antalet positionella argument inklusive args[0], plus
PY_VECTORCALL_ARGUMENTS_OFFSET
om värdet påargs[0]
tillfälligt kan ändras. Nyckelord-argument kan skickas precis som iPyObject_Vectorcall()
.Om objektet har funktionen
Py_TPFLAGS_METHOD_DESCRIPTOR
, kommer detta att anropa det obundna metodobjektet med hela args-vektorn som argument.Returnera resultatet av anropet om det lyckas, eller skapa ett undantag och returnera NULL om det misslyckas.
Tillagd i version 3.9.
API för samtalsstöd¶
-
int PyCallable_Check(PyObject *o)¶
- En del av Stabil ABI.
Bestäm om objektet o är anropsbart. Returnerar
1
om objektet är anropbart och0
annars. Denna funktion lyckas alltid.