Introduktion

Application Programmer’s Interface to Python ger C- och C++-programmerare tillgång till Python-tolken på en mängd olika nivåer. API:et är lika användbart från C++, men för korthetens skull kallas det i allmänhet för Python/C API. Det finns två fundamentalt olika anledningar till att använda Python/C API. Det första skälet är att skriva extension modules för specifika ändamål; dessa är C-moduler som utökar Python-tolken. Detta är förmodligen den vanligaste användningen. Det andra skälet är att använda Python som en komponent i en större applikation; denna teknik kallas i allmänhet embedding Python i en applikation.

Att skriva en tilläggsmodul är en relativt välkänd process, där en ”kokboks”-metod fungerar bra. Det finns flera verktyg som automatiserar processen i viss utsträckning. Även om människor har bäddat in Python i andra applikationer sedan dess tidiga existens, är processen att bädda in Python mindre okomplicerad än att skriva ett tillägg.

Många API-funktioner är användbara oberoende av om du bäddar in eller utökar Python; dessutom kommer de flesta applikationer som bäddar in Python att behöva tillhandahålla ett anpassat tillägg också, så det är förmodligen en bra idé att bekanta sig med att skriva ett tillägg innan du försöker bädda in Python i en riktig applikation.

Kompatibilitet med språkversioner

Pythons C API är kompatibelt med C11- och C++11-versionerna av C och C++.

Detta är en nedre gräns: C API kräver inte funktioner från senare C/C++-versioner. Du behöver inte aktivera din kompilators ”c11-läge”.

Kodningsstandarder

Om du skriver C-kod som ska ingå i CPython måste du följa de riktlinjer och standarder som definieras i PEP 7. Dessa riktlinjer gäller oavsett vilken version av Python du bidrar till. Att följa dessa konventioner är inte nödvändigt för dina egna tilläggsmoduler från tredje part, såvida du inte så småningom förväntar dig att bidra med dem till Python.

Inkludera filer

Alla funktions-, typ- och makrodefinitioner som behövs för att använda Python/C API inkluderas i din kod med följande rad:

#definiera PY_SSIZE_T_CLEAN
#inkludera <Python.h>

Detta innebär att följande standardrubriker måste inkluderas: <stdio.h>, <string.h>, <errno.h>, <limits.h>, <assert.h> och <stdlib.h> (om tillgängligt).

Anteckning

Eftersom Python kan definiera vissa preprocessordefinitioner som påverkar standardrubrikerna på vissa system, måste du inkludera Python.h innan några standardrubriker inkluderas.

Det rekommenderas att alltid definiera PY_SSIZE_T_CLEAN innan man inkluderar Python.h. Se Tolkning av argument och skapande av värden för en beskrivning av detta makro.

Alla användarsynliga namn som definieras av Python.h (utom de som definieras av de inkluderade standardheadern) har ett av prefixen Py eller _Py. Namn som börjar med _Py är för internt bruk av Python-implementationen och bör inte användas av tilläggsskrivare. Strukturmedlemsnamn har inget reserverat prefix.

Anteckning

Användarkod bör aldrig definiera namn som börjar med Py eller _Py. Detta förvirrar läsaren och äventyrar portabiliteten av användarkoden till framtida Python-versioner, som kan definiera ytterligare namn som börjar med något av dessa prefix.

Huvudfilerna installeras vanligtvis med Python. På Unix finns dessa i katalogerna prefix/include/pythonversion/ och exec_prefix/include/pythonversion/, där prefix och exec_prefix definieras av motsvarande parametrar i Pythons skript configure och version är '%d.%d' % sys.version_info[:2]. I Windows installeras sidhuvudet i prefix/include, där prefix är den installationskatalog som anges i installationsprogrammet.

För att inkludera rubrikerna, placera båda katalogerna (om de är olika) på kompilatorns sökväg för inkluderingar. Placera inte de överordnade katalogerna på sökvägen och använd sedan #include <pythonX.Y/Python.h>; detta kommer att gå sönder på multiplattformsbyggen eftersom de plattformsoberoende rubrikerna under prefix inkluderar de plattformsspecifika rubrikerna från exec_prefix.

C++-användare bör notera att även om API:et är definierat helt i C, deklarerar rubrikfilerna korrekt att ingångspunkterna är extern "C". Det finns därför inget behov av att göra något speciellt för att använda API:et från C++.

Användbara makron

Flera användbara makron finns definierade i Pythons header-filer. Många är definierade närmare där de är användbara (till exempel Py_RETURN_NONE, PyMODINIT_FUNC). Andra som är mer allmänt användbara definieras här. Detta är inte nödvändigtvis en fullständig lista.

Py_ABS(x)

Returnera det absoluta värdet av x.

Tillagd i version 3.3.

Py_ALWAYS_INLINE

Be kompilatorn att alltid inlinea en statisk inline-funktion. Kompilatorn kan ignorera det och bestämma sig för att inte inline-funktionen.

Den kan användas för att inline prestandakritiska statiska inline-funktioner när Python byggs i felsökningsläge med funktionsinlining inaktiverad. MSC inaktiverar till exempel inlining av funktioner när Python byggs i felsökningsläge.

Att blint markera en statisk inline-funktion med Py_ALWAYS_INLINE kan leda till sämre prestanda (till exempel på grund av ökad kodstorlek). Kompilatorn är vanligtvis smartare än utvecklaren när det gäller kostnads-/nyttoanalysen.

Om Python är byggd i debugläge (om makrot Py_DEBUG är definierat), gör makrot Py_ALWAYS_INLINE ingenting.

Den måste anges före funktionens returtyp. Användning:

statisk inline Py_ALWAYS_INLINE int random(void) { return 4; }

Tillagd i version 3.11.

Py_CHARMASK(c)

Argumentet måste vara ett tecken eller ett heltal i intervallet [-128, 127] eller [0, 255]. Detta makro returnerar c som kastats till en unsigned char.

Py_DEPRECATED(version)

Använd detta för föråldrade deklarationer. Makrot måste placeras före symbolnamnet.

Exempel:

Py_DEPRECATED(3.8) PyAPI_FUNC(int) Py_OldFunction(void);

Ändrad i version 3.8: Stöd för MSVC har lagts till.

Py_GETENV(s)

Som getenv(s), men returnerar NULL om -E angavs på kommandoraden (se PyConfig.use_environment).

Py_MAX(x, y)

Returnerar det maximala värdet mellan x och y.

Tillagd i version 3.3.

Py_MEMBER_SIZE(type, member)

Returnerar storleken på en struktur (type) member i bytes.

Tillagd i version 3.6.

Py_MIN(x, y)

Returnerar det minsta värdet mellan x och y.

Tillagd i version 3.3.

Py_NO_INLINE

Inaktivera inlining på en funktion. Det minskar till exempel C-stackens förbrukning: användbart på LTO+PGO-byggnader som innehåller mycket inline-kod (se bpo-33720).

Användning:

Py_NO_INLINE static int random(void) { return 4; }

Tillagd i version 3.11.

Py_STRINGIFY(x)

Konvertera x till en C-sträng. T.ex. Py_STRINGIFY(123) returnerar "123".

Tillagd i version 3.4.

Py_UNREACHABLE()

Använd detta när du har en kodväg som inte kan nås enligt designen. Till exempel i klausulen default: i ett switch-uttryck där alla möjliga värden täcks av case-uttryck. Använd detta på ställen där du kan vara frestad att sätta in ett assert(0) eller abort() -anrop.

I release-läge hjälper makrot kompilatorn att optimera koden och undviker en varning om onåbar kod. Makrot implementeras t.ex. med __builtin_unreachable() i GCC i release-läge.

En användning för Py_UNREACHABLE() är att följa ett anrop av en funktion som aldrig returnerar men som inte är deklarerad _Py_NO_RETURN.

Om en kodväg är mycket osannolik men kan nås i undantagsfall, får detta makro inte användas. Till exempel vid låg minneskapacitet eller om ett systemanrop returnerar ett värde som inte ligger inom det förväntade intervallet. I så fall är det bättre att rapportera felet till anroparen. Om felet inte kan rapporteras till anroparen kan Py_FatalError() användas.

Tillagd i version 3.7.

Py_UNUSED(arg)

Använd detta för oanvända argument i en funktionsdefinition för att tysta kompilatorvarningar. Exempel: int func(int a, int Py_UNUSED(b)) { return a; }.

Tillagd i version 3.4.

PyDoc_STRVAR(name, str)

Skapar en variabel med namnet name som kan användas i docstrings. Om Python byggs utan dokumentsträngar kommer värdet att vara tomt.

Använd PyDoc_STRVAR för docstrings för att stödja byggandet av Python utan docstrings, enligt specifikationen i PEP 7.

Exempel:

PyDoc_STRVAR(pop_doc, "Ta bort och returnera elementet längst till höger.");

statisk PyMethodDef deque_methods[] = {
    // ...
    {"pop", (PyCFunction)deque_pop, METH_NOARGS, pop_doc},
    // ...
}
PyDoc_STR(str)

Skapar en docstring för den angivna indatasträngen eller en tom sträng om docstrings är inaktiverade.

Använd PyDoc_STR vid angivande av dokumentsträngar för att stödja byggandet av Python utan dokumentsträngar, enligt PEP 7.

Exempel:

static PyMethodDef pysqlite_row_methods[] = {
    {"keys", (PyCFunction)pysqlite_row_keys, METH_NOARGS,
        PyDoc_STR("Returnerar nycklarna för raden.")},
    {NULL, NULL}
};

Objekt, typer och referensräkningar

De flesta Python/C API-funktioner har ett eller flera argument samt ett returvärde av typen PyObject*. Denna typ är en pekare till en opak datatyp som representerar ett godtyckligt Python-objekt. Eftersom alla Python-objekttyper behandlas på samma sätt av Python-språket i de flesta situationer (t.ex. tilldelningar, scope-regler och argumentpassning) är det bara passande att de representeras av en enda C-typ. Nästan alla Python-objekt lever på högen: du kan aldrig deklarera en automatisk eller statisk variabel av typen PyObject, endast pekarvariabler av typen PyObject* kan deklareras. Det enda undantaget är typobjekten; eftersom dessa aldrig får avallokeras är de typiskt statiska PyTypeObject-objekt.

Alla Python-objekt (även Pythons heltal) har en typ och ett referensantal. Ett objekts typ avgör vilken typ av objekt det är (t.ex. ett heltal, en lista eller en användardefinierad funktion; det finns många fler som förklaras i Standardtypens hierarki). För var och en av de välkända typerna finns det ett makro för att kontrollera om ett objekt är av den typen; till exempel är PyList_Check(a) sant om (och endast om) det objekt som a pekar på är en Python-lista.

Referensräkningar

Referensräkningen är viktig eftersom dagens datorer har en ändlig (och ofta starkt begränsad) minnesstorlek; den räknar hur många olika platser det finns som har en strong reference till ett objekt. En sådan plats kan vara ett annat objekt, eller en global (eller statisk) C-variabel, eller en lokal variabel i någon C-funktion. När den sista strong reference till ett objekt släpps (d.v.s. dess referensantal blir noll), deallokeras objektet. Om det innehåller referenser till andra objekt, frigörs dessa referenser. Dessa andra objekt kan i sin tur deallokeras om det inte finns några fler referenser till dem, och så vidare. (Det finns ett uppenbart problem med objekt som refererar till varandra här; för tillfället är lösningen ”gör inte det.”)

Referensräkningar manipuleras alltid explicit. Det normala sättet är att använda makrot Py_INCREF() för att ta en ny referens till ett objekt (dvs. öka dess referensantal med ett) och Py_DECREF() för att släppa den referensen (dvs. minska referensantalet med ett). Makrot Py_DECREF() är betydligt mer komplext än incref, eftersom det måste kontrollera om referensantalet blir noll och därefter anropa objektets deallocator. Deallokatorn är en funktionspoängare som ingår i objektets typstruktur. Den typspecifika deallokatorn tar hand om att frigöra referenser för andra objekt som ingår i objektet om detta är en sammansatt objekttyp, till exempel en lista, samt utför ytterligare slutbehandling som behövs. Det finns ingen chans att referensantalet kan överskridas; minst lika många bitar används för att hålla referensantalet som det finns distinkta minnesplatser i det virtuella minnet (förutsatt att sizeof(Py_ssize_t) >= sizeof(void*)). Således är ökningen av referensantalet en enkel operation.

Det är inte nödvändigt att hålla en strong reference (d.v.s. öka referensantalet) för varje lokal variabel som innehåller en pekare till ett objekt. I teorin ökar objektets referensantal med ett när variabeln pekar på det och det minskar med ett när variabeln försvinner ur räckvidden. Dessa två tar dock ut varandra, så i slutändan har referensantalet inte ändrats. Det enda egentliga skälet till att använda referensantalet är att förhindra att objektet avallokeras så länge vår variabel pekar på det. Om vi vet att det finns minst en annan referens till objektet som lever minst lika länge som vår variabel, finns det inget behov av att tillfälligt ta en ny strong reference (dvs. öka referensantalet). En viktig situation där detta uppstår är i objekt som skickas som argument till C-funktioner i en tilläggsmodul som anropas från Python; anropsmekanismen garanterar att hålla en referens till varje argument så länge anropet varar.

En vanlig fallgrop är dock att extrahera ett objekt från en lista och behålla det ett tag utan att ta en ny referens. Någon annan operation kan tänkas ta bort objektet från listan, släppa referensen och eventuellt avallokera den. Den verkliga faran är att oskyldigt utseende operationer kan åberopa godtycklig Python-kod som kan göra detta; det finns en kodväg som gör att kontrollen kan flöda tillbaka till användaren från en Py_DECREF(), så nästan alla operationer är potentiellt farliga.

Ett säkert tillvägagångssätt är att alltid använda de generiska operationerna (funktioner vars namn börjar med PyObject_, PyNumber_, PySequence_ eller PyMapping_). Dessa operationer skapar alltid en ny strong reference (dvs. ökar referensantalet) för det objekt som de returnerar. Detta lämnar anroparen med ansvaret att anropa Py_DECREF() när de är klara med resultatet; detta blir snart en andra natur.

Referensräkning Detaljer

Referensräkningsbeteendet för funktioner i Python/C API förklaras bäst i termer av ägarskap av referenser. Äganderätten gäller referenser, aldrig objekt (objekt ägs inte, de delas alltid). att ”äga en referens” innebär att man är ansvarig för att anropa Py_DECREF på den när referensen inte längre behövs. Ägandet kan också överföras, vilket innebär att den kod som får ägandet av referensen sedan blir ansvarig för att så småningom släppa den genom att anropa Py_DECREF() eller Py_XDECREF() när den inte längre behövs—eller överföra detta ansvar (vanligtvis till dess anropare). När en funktion överför ägandet av en referens till sin anropare, sägs anroparen få en ny referens. När inget ägande överförs sägs den som anropar låna referensen. Ingenting behöver göras för en lånad referens.

Omvänt, när en anropande funktion skickar en referens till ett objekt, finns det två möjligheter: funktionen stjäl en referens till objektet, eller så gör den det inte. Att stjäla en referens innebär att när du skickar en referens till en funktion, antar den funktionen att den nu äger referensen och att du inte längre är ansvarig för den.

Få funktioner stjäl referenser; de två anmärkningsvärda undantagen är PyList_SetItem() och PyTuple_SetItem(), som stjäl en referens till objektet (men inte till den tupel eller lista som objektet läggs i!). Dessa funktioner utformades för att stjäla en referens på grund av ett vanligt idiom för att fylla en tupel eller lista med nyskapade objekt; till exempel skulle koden för att skapa tupeln (1, 2, "three") kunna se ut så här (vi glömmer bort felhantering för tillfället; ett bättre sätt att koda detta visas nedan):

PyObject *t;

t = PyTuple_New(3);
PyTuple_SetItem(t, 0, PyLong_FromLong(1L));
PyTuple_SetItem(t, 1, PyLong_FromLong(2L));
PyTuple_SetItem(t, 2, PyUnicode_FromString("tre"));

Här returnerar PyLong_FromLong() en ny referens som omedelbart stjäls av PyTuple_SetItem(). När du vill fortsätta använda ett objekt trots att referensen till det kommer att stjälas, använd Py_INCREF() för att ta en annan referens innan du anropar den referensstjälande funktionen.

För övrigt är PyTuple_SetItem() det endaste sättet att ställa in tupelobjekt; PySequence_SetItem() och PyObject_SetItem() vägrar att göra detta eftersom tuplar är en oföränderlig datatyp. Du bör endast använda PyTuple_SetItem() för tuples som du skapar själv.

Motsvarande kod för att fylla på en lista kan skrivas med PyList_New() och PyList_SetItem().

I praktiken kommer du dock sällan att använda dessa sätt att skapa och fylla i en tupel eller lista. Det finns en generisk funktion, Py_BuildValue(), som kan skapa de flesta vanliga objekt från C-värden, styrda av en formatsträng. Till exempel kan de två ovanstående kodblocken ersättas av följande (som också tar hand om felkontrollen):

PyObject *tuple, *list;

tuple = Py_BuildValue("(iis)", 1, 2, "three");
list = Py_BuildValue("[iis]", 1, 2, "three");

Det är mycket vanligare att använda PyObject_SetItem() och vänner med objekt vars referenser du bara lånar, som argument som skickades in till den funktion du skriver. I så fall är deras beteende när det gäller referenser mycket sundare, eftersom du inte behöver ta en ny referens bara för att kunna ge bort den referensen (”låta den bli stulen”). Den här funktionen ställer till exempel in alla objekt i en lista (egentligen vilken mutabel sekvens som helst) till ett givet objekt:

int
set_all(PyObject *target, PyObject *item)
{
    Py_ssize_t i, n;

    n = PyObject_Length(mål);
    if (n < 0)
        returnera -1;
    for (i = 0; i < n; i++) {
        PyObject *index = PyLong_FromSsize_t(i);
        if (!index)
            returnera -1;
        if (PyObject_SetItem(target, index, item) < 0) {
            Py_DECREF(index);
            return -1;
        }
        Py_DECREF(index);
    }
    return 0;
}

Situationen är något annorlunda för funktioners returvärden. Att skicka en referens till de flesta funktioner ändrar inte ditt ägaransvar för den referensen, men många funktioner som returnerar en referens till ett objekt ger dig äganderätten till referensen. Anledningen är enkel: i många fall skapas det returnerade objektet i farten, och den referens du får är den enda referensen till objektet. Därför returnerar de generiska funktioner som returnerar objektreferenser, som PyObject_GetItem() och PySequence_GetItem(), alltid en ny referens (den som anropar blir ägare till referensen).

Det är viktigt att inse att om du äger en referens som returneras av en funktion beror på vilken funktion du anropar — fjäderdräkten (typen av objekt som skickas som argument till funktionen) inte spelar någon roll! Om du extraherar ett objekt från en lista med hjälp av PyList_GetItem(), äger du inte referensen — men om du hämtar samma objekt från samma lista med hjälp av PySequence_GetItem() (som råkar ta exakt samma argument), äger du en referens till det returnerade objektet.

Här är ett exempel på hur du kan skriva en funktion som beräknar summan av posterna i en lista med heltal; en gång med PyList_GetItem() och en gång med PySequence_GetItem().

long
sum_list(PyObject *list)
{
    Py_ssize_t i, n;
    long total = 0, value;
    PyObject *item;

    n = PyList_Size(list);
    if (n < 0)
        return -1; /* Not a list */
    for (i = 0; i < n; i++) {
        item = PyList_GetItem(list, i); /* Can't fail */
        if (!PyLong_Check(item)) continue; /* Skip non-integers */
        value = PyLong_AsLong(item);
        if (value == -1 && PyErr_Occurred())
            /* Integer too big to fit in a C long, bail out */
            return -1;
        total += value;
    }
    return total;
}
long
sum_sequence(PyObject *sequence)
{
    Py_ssize_t i, n;
    long total = 0, value;
    PyObject *item;
    n = PySequence_Length(sequence);
    if (n < 0)
        return -1; /* Has no length */
    for (i = 0; i < n; i++) {
        item = PySequence_GetItem(sequence, i);
        if (item == NULL)
            return -1; /* Not a sequence, or other failure */
        if (PyLong_Check(item)) {
            value = PyLong_AsLong(item);
            Py_DECREF(item);
            if (value == -1 && PyErr_Occurred())
                /* Integer too big to fit in a C long, bail out */
                return -1;
            total += value;
        }
        else {
            Py_DECREF(item); /* Discard reference ownership */
        }
    }
    return total;
}

Typer

Det finns få andra datatyper som spelar en viktig roll i Python/C API; de flesta är enkla C-typer som int, long, double och char*. Några strukturtyper används för att beskriva statiska tabeller som används för att lista de funktioner som exporteras av en modul eller dataattributen för en ny objekttyp, och en annan används för att beskriva värdet av ett komplext tal. Dessa kommer att diskuteras tillsammans med de funktioner som använder dem.

type Py_ssize_t
En del av Stabil ABI.

En signerad integraltyp som är sådan att sizeof(Py_ssize_t) == sizeof(size_t). C99 definierar inte en sådan sak direkt (size_t är en osignerad integraltyp). Se PEP 353 för detaljer. PY_SSIZE_T_MAX är det största positiva värdet av typen Py_ssize_t.

Undantag

Python-programmeraren behöver bara hantera undantag om specifik felhantering krävs; ohanterade undantag sprids automatiskt till anroparen, sedan till anroparens anropar och så vidare, tills de når tolken på högsta nivån, där de rapporteras till användaren tillsammans med en stack-traceback.

För C-programmerare måste dock felkontrollen alltid vara explicit. Alla funktioner i Python/C API kan skapa undantag, såvida inte något annat uttryckligen anges i en funktions dokumentation. I allmänhet, när en funktion stöter på ett fel, ställer den in ett undantag, kasserar alla objektreferenser som den äger och returnerar en felindikator. Om inte annat dokumenteras är denna indikator antingen NULL eller -1, beroende på funktionens returtyp. Ett fåtal funktioner returnerar ett booleskt sant/falskt resultat, där false indikerar ett fel. Mycket få funktioner returnerar ingen explicit felindikator eller har ett tvetydigt returvärde, och kräver explicit testning för fel med PyErr_Occurred(). Dessa undantag är alltid explicit dokumenterade.

Undantagstillstånd lagras per tråd (detta motsvarar att använda global lagring i ett otrådat program). En tråd kan befinna sig i ett av två tillstånd: ett undantag har inträffat eller inte. Funktionen PyErr_Occurred() kan användas för att kontrollera detta: den returnerar en lånad referens till undantagstypsobjektet när ett undantag har inträffat, och NULL annars. Det finns ett antal funktioner för att ställa in undantagstillståndet: PyErr_SetString() är den vanligaste (men inte den mest allmänna) funktionen för att ställa in undantagstillståndet, och PyErr_Clear() rensar undantagstillståndet.

Det fullständiga undantagstillståndet består av tre objekt (som alla kan vara NULL): undantagstypen, det motsvarande undantagsvärdet och spårningen. Dessa har samma betydelser som Python-resultatet av sys.exc_info(); men de är inte desamma: Python-objekten representerar det sista undantaget som hanteras av en Python tryexcept-sats, medan undantagstillståndet på C-nivå bara existerar medan ett undantag skickas vidare mellan C-funktioner tills det når Python-bytekodtolkarens huvudslinga, som tar hand om att överföra det till sys.exc_info() och vänner.

Observera att från och med Python 1.5 är det föredragna, trådsäkra sättet att komma åt undantagstillståndet från Python-kod att anropa funktionen sys.exc_info(), som returnerar undantagstillståndet per tråd för Python-kod. Semantiken för båda sätten att komma åt undantagstillståndet har också ändrats så att en funktion som fångar upp ett undantag sparar och återställer trådens undantagstillstånd så att anroparens undantagstillstånd bevaras. Detta förhindrar vanliga buggar i undantagshanteringskod som orsakas av att en oskyldig funktion skriver över det undantag som hanteras; det minskar också den ofta oönskade livstidsförlängningen för objekt som refereras till av stackramarna i spårningen.

Som en allmän princip bör en funktion som anropar en annan funktion för att utföra någon uppgift kontrollera om den anropade funktionen gav upphov till ett undantag och i så fall vidarebefordra undantagstillståndet till sin anropare. Den bör kasta bort alla objektreferenser som den äger och returnera en felindikator, men den bör inte ställa in ett annat undantag — det skulle skriva över det undantag som just har uppstått och förlora viktig information om den exakta orsaken till felet.

Ett enkelt exempel på hur man upptäcker undantag och skickar dem vidare visas i sum_sequence()-exemplet ovan. Det råkar vara så att det här exemplet inte behöver rensa upp några ägda referenser när det upptäcker ett fel. Följande exempel på funktion visar en del felrensning. Först, för att påminna dig om varför du gillar Python, visar vi motsvarande Python-kod:

def incr_item(dict, nyckel):
    try:
        item = dict[nyckel]
    except KeyError:
        objekt = 0
    dict[nyckel] = objekt + 1

Här är motsvarande C-kod, i all sin prakt:

int
incr_item(PyObject *dict, PyObject *key)
{
    /* Alla objekt initialiseras till NULL för Py_XDECREF */
    PyObject *item = NULL, *const_one = NULL, *incremented_item = NULL;
    int rv = -1; /* Returvärde initialiserat till -1 (misslyckande) */

    item = PyObject_GetItem(dict, nyckel);
    if (item == NULL) {
        /* Hantera endast KeyError: */
        if (!PyErr_ExceptionMatches(PyExc_KeyError))
            goto fel;

        /* Rensa felet och använd noll: */
        PyErr_Clear();
        objekt = PyLong_FromLong(0L);
        if (objekt == NULL)
            goto fel;
    }
    const_one = PyLong_FromLong(1L);
    om (const_one == NULL)
         till fel;

    incremented_item = PyNumber_Add(item, const_one);
    if (incremented_item == NULL)
        goto fel;

    if (PyObject_SetItem(dict, key, incremented_item) < 0)
        goto fel;
    rv = 0; /* Framgång */
    /* Fortsätt med uppstädningskod */

 error (fel):
    /* Uppstädningskod, delas av framgångs- och felväg */

    /* Använd Py_XDECREF() för att ignorera NULL-referenser */
    Py_XDECREF(objekt);
    Py_XDECREF(const_one);
    Py_XDECREF(incremented_item);

    return rv; /* -1 för fel, 0 för framgång */
}

Detta exempel representerar en godkänd användning av goto-satsen i C! Det illustrerar användningen av PyErr_ExceptionMatches() och PyErr_Clear() för att hantera specifika undantag, och användningen av Py_XDECREF() för att göra sig av med ägda referenser som kan vara NULL (notera 'X' i namnet; Py_DECREF() skulle krascha när den konfronteras med en NULL-referens). Det är viktigt att de variabler som används för att hålla ägda referenser initialiseras till NULL för att detta ska fungera; på samma sätt initialiseras det föreslagna returvärdet till -1 (misslyckande) och sätts först till framgång efter att det sista anropet som görs är framgångsrikt.

Inbäddning av Python

Den enda viktiga uppgift som endast inbäddare (i motsats till författare av tillägg) av Python-tolken behöver bekymra sig om är initialiseringen, och eventuellt slutförandet, av Python-tolken. De flesta funktioner i tolken kan bara användas efter att tolken har initialiserats.

Den grundläggande initialiseringsfunktionen är Py_Initialize(). Den initierar tabellen över inlästa moduler och skapar de grundläggande modulerna builtins, __main__ och sys. Den initialiserar också sökvägen för modulerna (sys.path).

Py_Initialize() ställer inte in ”script argument list” (sys.argv). Om denna variabel behövs av Python-kod som kommer att exekveras senare, måste PyConfig.argv och PyConfig.parse_argv sättas: se Python Initialization Configuration.

På de flesta system (i synnerhet på Unix och Windows, även om detaljerna är något annorlunda) beräknar Py_Initialize() modulens sökväg baserat på sin bästa gissning om platsen för Python-tolkens körbara standardprogram, förutsatt att Python-biblioteket finns på en fast plats i förhållande till Python-tolkens körbara program. I synnerhet letar den efter en katalog med namnet lib/pythonX.Y i förhållande till den överordnade katalog där den körbara filen med namnet python finns i sökvägen för skalkommandon (miljövariabeln PATH).

Om till exempel den körbara Python-filen finns i /usr/local/bin/python, kommer den att anta att biblioteken finns i /usr/local/lib/pythonX.Y. (Faktum är att den här sökvägen också är ”fallback”-platsen, som används när ingen körbar fil med namnet python hittas längs PATH) Användaren kan åsidosätta detta beteende genom att ställa in miljövariabeln PYTHONHOME, eller lägga till ytterligare kataloger framför standardsökvägen genom att ställa in PYTHONPATH.

Den inbäddande applikationen kan styra sökningen genom att ställa in PyConfig.program_name innan anropa Py_InitializeFromConfig(). Observera att PYTHONHOME fortfarande åsidosätter detta och att PYTHONPATH fortfarande infogas framför standardsökvägen. En applikation som kräver total kontroll måste tillhandahålla sin egen implementation av Py_GetPath(), Py_GetPrefix(), Py_GetExecPrefix() och Py_GetProgramFullPath() (alla definierade i Modules/getpath.c).

Ibland är det önskvärt att ”avinitialisera” Python. Till exempel kan programmet vilja börja om från början (göra ett nytt anrop till Py_Initialize()) eller så är programmet helt enkelt färdigt med att använda Python och vill frigöra minne som allokerats av Python. Detta kan åstadkommas genom att anropa Py_FinalizeEx(). Funktionen Py_IsInitialized() returnerar true om Python för närvarande är i det initialiserade tillståndet. Mer information om dessa funktioner ges i ett senare kapitel. Observera att Py_FinalizeEx() inte frigör allt minne som allokerats av Python-tolken, t.ex. minne som allokerats av tilläggsmoduler kan för närvarande inte frigöras.

Felsökning av byggnader

Python kan byggas med flera makron för att aktivera extra kontroller av tolken och tilläggsmoduler. Dessa kontroller tenderar att lägga till en stor mängd overhead till körtiden så de är inte aktiverade som standard.

En fullständig lista över de olika typerna av felsökningsbyggnader finns i filen Misc/SpecialBuilds.txt i Python-källdistributionen. Det finns builds som stöder spårning av referensräkningar, felsökning av minnesallokeraren eller lågnivåprofilering av huvudtolkens loop. I resten av detta avsnitt beskrivs endast de mest frekvent använda byggnaderna.

Py_DEBUG

Kompilering av tolken med makrot Py_DEBUG definierat ger vad som i allmänhet menas med en debug-byggnad av Python. Py_DEBUG aktiveras i Unix-byggnaden genom att lägga till --with-pydebug till kommandot ./configure. Det är också underförstått genom närvaron av det icke-Python-specifika _DEBUG-makrot. När Py_DEBUG är aktiverat i Unix-versionen är kompilatoroptimeringen inaktiverad.

Utöver den felsökning av referensantal som beskrivs nedan utförs extra kontroller, se Python Debug Build.

Genom att definiera Py_TRACE_REFS aktiveras referensspårning (se configure --with-trace-refs option). När den definieras upprätthålls en cirkulär dubbellänkad lista över aktiva objekt genom att lägga till två extra fält till varje PyObject. Totala allokeringar spåras också. Vid avslut skrivs alla befintliga referenser ut. (I interaktivt läge sker detta efter varje sats som körs av tolken)

Se Misc/SpecialBuilds.txt i Python-källdistributionen för mer detaljerad information.