1.以 C 或 C++ 擴充 Python

如果你會撰寫 C 程式語言,那要向 Python 新增內建模組就不困難。這種擴充模組 (extension modules) 可以做兩件在 Python 中無法直接完成的事:它們可以實作新的內建物件型別,並且可以呼叫 C 的函式庫函式和系統呼叫。

為了支援擴充,Python API (Application Programmers Interface) 定義了一組函式、巨集和變數,提供對 Python run-time 系統大部分面向的存取。Python API 是透過引入標頭檔"Python.h" 來被納入到一個 C 原始碼檔案中。

擴充模組的編譯取決於其預期用途以及你的系統設定;詳細資訊將在後面的章節中提供。

備註

C 擴充介面是 CPython 所特有的,擴充模組在其他 Python 實作上無法運作。在許多情況下,可以避免撰寫 C 擴充並保留對其他實作的可移植性。例如,如果你的用例是呼叫 C 函式庫函式或系統呼叫,你應該考慮使用ctypes 模組或cffi 函式庫,而不是編寫自定義的 C 程式碼。這些模組讓你可以撰寫 Python 程式碼來與 C 程式碼介接,而且比起撰寫和編譯 C 擴充模組,這些模組在 Python 實作之間更容易移植。

1.1.一個簡單範例

讓我們來建立一個叫做spam(Monty Python 粉絲最愛的食物...)的擴充模組。假設我們要建立一個 Python 介面給 C 函式庫的函式system()[1] 使用,這個函式接受一個以 null 終止的 (null-terminated) 字元字串做為引數,並回傳一個整數。我們希望這個函式可以在 Python 中被呼叫,如下所示:

>>>importspam>>>status=spam.system("ls -l")

首先建立一個檔案spammodule.c。(從過去歷史來看,如果一個模組叫做spam,包含其實作的 C 檔案就會叫做spammodule.c;如果模組名稱很長,像是spammify,模組名稱也可以只是spammify.c)。

我們檔案的前兩列可以為:

#define PY_SSIZE_T_CLEAN#include<Python.h>

這會將 Python API 拉進來(你可以加入註解來說明模組的目的,也可以加入版權聲明)。

備註

由於 Python 可能定義一些影響系統上某些標準標頭檔的預處理器定義,你必須在引入任何標準標頭檔之前引入Python.h

#definePY_SSIZE_T_CLEAN 被用來表示在某些 API 中應該使用Py_ssize_t 而不是int。自 Python 3.13 起,它就不再是必要的了,但我們在此保留它以便向後相容。關於這個巨集的描述請參閱Strings and buffers

除了那些在標準標頭檔中定義的符號以外,所有由Python.h 定義的使用者可見符號 (user-visible symbols) 的前綴都是PyPY。為了方便,也因為 Python 直譯器的大量使用,"Python.h" 也引入了一些標準的標頭檔:<stdio.h><string.h><errno.h><stdlib.h>。如果<stdlib.h> 在你的系統上不存在,它會直接宣告malloc()free()realloc() 函式。

接下來我們要加入到模組檔案的是 C 函式,當 Python 運算式spam.system(string) 要被求值 (evaluated) 時就會被呼叫(我們很快就會看到它最後是如何被呼叫的):

staticPyObject*spam_system(PyObject*self,PyObject*args){constchar*command;intsts;if(!PyArg_ParseTuple(args,"s",&command))returnNULL;sts=system(command);returnPyLong_FromLong(sts);}

可以很直觀地從 Python 的引數串列(例如單一的運算式"ls-l")直接轉換成傳給 C 函式的引數。C 函式總是有兩個引數,習慣上會命名為selfargs

對於模組層級的函式,self 引數會指向模組物件;而對於方法來說則是指向物件的實例。

args 引數會是一個指向包含引數的 Python 元組物件的指標。元組中的每一項都對應於呼叫的引數串列中的一個引數。引數是 Python 物件 --- 為了在我們的 C 函式中對它們做任何事情,我們必須先將它們轉換成 C 值。Python API 中的PyArg_ParseTuple() 函式能夠檢查引數型別並將他們轉換為 C 值。它使用模板字串來決定所需的引數型別以及儲存轉換值的 C 變數型別。稍後會再詳細說明。

如果所有的引數都有正確的型別,且其元件已儲存在傳入位址的變數中,則PyArg_ParseTuple() 會回傳 true(非零)。如果傳入的是無效引數串列則回傳 false(零)。在後者情況下,它也會產生適當的例外,因此呼叫函式可以立即回傳NULL(就像我們在範例中所看到的)。

1.2.插曲:錯誤與例外

在整個 Python 直譯器中的一個重要慣例為:當一個函式失敗時,它就應該設定一個例外條件,並回傳一個錯誤值(通常是-1 或一個NULL 指標)。例外資訊會儲存在直譯器執行緒狀態的三個成員中。如果沒有例外,它們就會是NULL。否則,它們是由sys.exc_info() 所回傳的 Python 元組中的 C 等效元組。它們是例外型別、例外實例和回溯物件。了解它們對於理解錯誤是如何傳遞是很重要的。

Python API 定義了許多能夠設定各種類型例外的函式。

最常見的是PyErr_SetString()。它的引數是一個例外物件和一個 C 字串。例外物件通常是預先定義的物件,例如PyExc_ZeroDivisionError。C 字串則指出錯誤的原因,並被轉換為 Python 字串物件且被儲存為例外的「關聯值 (associated value)」。

另一個有用的函式是PyErr_SetFromErrno(),它只接受一個例外引數,並透過檢查全域變數errno 來建立關聯值。最一般的函式是PyErr_SetObject(),它接受兩個物件引數,即例外和它的關聯值。你不需要對傳給任何這些函式的物件呼叫Py_INCREF()

你可以使用PyErr_Occurred() 來不具破壞性地測試例外是否已被設定。這會回傳目前的例外物件,如果沒有例外發生則回傳NULL。你通常不需要呼叫PyErr_Occurred() 來查看函式呼叫是否發生錯誤,因為你應可從回傳值就得知。

當函式f 呼叫另一個函式g 時檢測到後者失敗,f 本身應該回傳一個錯誤值(通常是NULL-1)。它應該呼叫PyErr_* 函式的其中一個,這會已被g 呼叫過。f 的呼叫者然後也應該回傳一個錯誤指示給它的呼叫者,同樣不會呼叫PyErr_*,依此類推 --- 最詳細的錯誤原因已經被首先檢測到它的函式回報了。一旦錯誤到達 Python 直譯器的主要迴圈,這會中止目前執行的 Python 程式碼,並嘗試尋找 Python 程式設計者指定的例外處理程式。

(在某些情況下,模組可以透過呼叫另一個PyErr_* 函式來提供更詳細的錯誤訊息,在這種情況下這樣做是沒問題的。然而這一般來說並非必要,而且可能會導致錯誤原因資訊的遺失:大多數的操作都可能因為各種原因而失敗。)

要忽略由函式呼叫失敗所設定的例外,必須明確地呼叫PyErr_Clear() 來清除例外條件。C 程式碼唯一要呼叫PyErr_Clear() 的情況為當它不想將錯誤傳遞給直譯器而想要完全是自己來處理它時(可能是要再嘗試其他東西,或者假裝什麼都沒出錯)。

每個失敗的malloc() 呼叫都必須被轉換成一個例外 ---malloc()(或realloc())的直接呼叫者必須呼叫PyErr_NoMemory() 並回傳一個失敗指示器。所有建立物件的函式(例如PyLong_FromLong())都已經這麼做了,所以這個注意事項只和那些直接呼叫malloc() 的函式有關。

還要注意的是,有PyArg_ParseTuple() 及同系列函式的這些重要例外,回傳整數狀態的函式通常會回傳一個正值或 0 表示成功、回傳-1 表示失敗,就像 Unix 系統呼叫一樣。

最後,在回傳錯誤指示器時要注意垃圾清理(透過對你已經建立的物件呼叫Py_XDECREF()Py_DECREF())!

你完全可以自行選擇要產生的例外。有一些預先宣告的 C 物件會對應到所有內建的 Python 例外,例如PyExc_ZeroDivisionError,你可以直接使用它們。當然,你應該明智地選擇例外,像是不要使用PyExc_TypeError 來表示檔案無法打開(應該是PyExc_OSError)。如果引數串列有問題,PyArg_ParseTuple() 函式通常會引發PyExc_TypeError。如果你有一個引數的值必須在一個特定的範圍內或必須滿足其他條件,則可以使用PyExc_ValueError

你也可以定義一個你的模組特有的新例外。為此你通常會在檔案開頭宣告一個靜態物件變數:

staticPyObject*SpamError;

並在你的模組初始化函式中使用一個例外物件來初始化它 (PyInit_spam()):

PyMODINIT_FUNCPyInit_spam(void){PyObject*m;m=PyModule_Create(&spammodule);if(m==NULL)returnNULL;SpamError=PyErr_NewException("spam.error",NULL,NULL);if(PyModule_AddObjectRef(m,"error",SpamError)<0){Py_CLEAR(SpamError);Py_DECREF(m);returnNULL;}returnm;}

請注意,例外物件的 Python 名稱是spam.error。如同內建的例外所述,PyErr_NewException() 函式可能會建立一個基底類別為Exception 的類別(除非傳入另一個類別來代替NULL)。

請注意,SpamError 變數保留了對新建立的例外類別的參照;這是故意的!因為外部程式碼可能會從模組中移除這個例外,所以需要一個對這個類別的參照來確保它不會被丟棄而導致SpamError 變成一個迷途指標 (dangling pointer)。如果它變成迷途指標,那產生例外的 C 程式碼可能會導致核心轉儲 (core dump) 或其他不預期的 side effect。

我們稍後會討論PyMODINIT_FUNC 作為函式回傳型別的用法。

可以在你的擴充模組中呼叫PyErr_SetString() 來引發spam.error 例外,如下所示:

staticPyObject*spam_system(PyObject*self,PyObject*args){constchar*command;intsts;if(!PyArg_ParseTuple(args,"s",&command))returnNULL;sts=system(command);if(sts<0){PyErr_SetString(SpamError,"System command failed");returnNULL;}returnPyLong_FromLong(sts);}

1.3.回到範例

回到我們的範例函式,現在你應該可以理解這個陳述式了:

if(!PyArg_ParseTuple(args,"s",&command))returnNULL;

如果在引數串列中檢測到錯誤則會回傳NULL(回傳物件指標之函式的錯誤指示器),其依賴於PyArg_ParseTuple() 設定的例外,否則引數的字串值會已被複製到區域變數command 中。這是一個指標賦值,你不應該修改它所指向的字串(所以在標準 C 中,command 變數應該正確地被宣告為constchar*command)。

接下來的陳述式會呼叫 Unix 函式system(),並將剛才從PyArg_ParseTuple() 得到的字串傳給它:

sts=system(command);

我們的spam.system() 函式必須以 Python 物件的形式來回傳sts 的值。這是透過PyLong_FromLong() 函式來達成。

returnPyLong_FromLong(sts);

在這種情況下它會回傳一個整數物件。(是的,在 Python 中連整數也是堆積 (heap) 上的物件!)

如果你有一個不回傳任何有用引數的 C 函式(一個回傳void 的函式),對應的 Python 函式必須回傳None。你需要以下這個慣例來達成(由Py_RETURN_NONE 巨集實作):

Py_INCREF(Py_None);returnPy_None;

Py_None 是特殊 Python 物件None 的 C 名稱。它是一個真正的 Python 物件而不是一個NULL 指標,在大多數的情況下它的意思是「錯誤」,如我們所見過的那樣。

1.4.模組的方法表和初始化函式

我承諾過要展示spam_system() 是如何從 Python 程式中呼叫的。首先,我們需要在「方法表」中列出它的名稱和位址:

staticPyMethodDefSpamMethods[]={...{"system",spam_system,METH_VARARGS,"Execute a shell command."},...{NULL,NULL,0,NULL}/* Sentinel */};

請注意第三個項目 (METH_VARARGS)。這是一個告訴直譯器 C 函式之呼叫方式的旗標。通常應該是METH_VARARGSMETH_VARARGS|METH_KEYWORDS0 表示是使用PyArg_ParseTuple() 的一個過時變體。

當只使用METH_VARARGS 時,函式應預期 Python 層級的參數是以元組形式傳入且能夠接受以PyArg_ParseTuple() 進行剖析;有關此函式的更多資訊將在下面提供。

如果要將關鍵字引數傳給函式,可以在第三個欄位設定METH_KEYWORDS 位元。在這種情況下,C 函式應該要能接受第三個PyObject* 參數,這個參數將會是關鍵字的字典。可使用PyArg_ParseTupleAndKeywords() 來剖析這種函式的引數。

方法表必須在模組定義結構中被參照:

staticstructPyModuleDefspammodule={PyModuleDef_HEAD_INIT,"spam",/* 模組名稱 */spam_doc,/* 模組文件,可能為 NULL */-1,/* 模組的個別直譯器狀態的大小,                 如果模組將狀態保存在全域變數中則為 -1 */SpamMethods};

反過來說,這個結構必須在模組的初始化函式中被傳給直譯器。初始化函式必須被命名為PyInit_name(),其中name 是模組的名稱,且應該是模組檔案中唯一定義的非「靜態 (static)」項目:

PyMODINIT_FUNCPyInit_spam(void){returnPyModule_Create(&spammodule);}

請注意,PyMODINIT_FUNC 宣告函式的回傳型別為PyObject*、宣告平台所需的任何特殊連結宣告、並針對 C++ 宣告函式為extern"C"

當 Python 程式第一次引入模組spam 時,PyInit_spam() 會被呼叫。(有關嵌入 Python 的註解請參見下文。)它會呼叫回傳一個模組物件的PyModule_Create(),並根據在模組定義中所找到的表(一個PyMethodDef 結構的陣列)將內建的函式物件插入到新建立的模組中。PyModule_Create() 會回傳一個指向它建立之模組物件的指標。對於某些錯誤情況,它可能會以嚴重錯誤的形式來中止;如果模組無法令人滿意地被初始化,它也會回傳NULL。初始化函式必須把模組物件回傳給它的呼叫者,這樣它才會被插入到sys.modules 中。

嵌入 Python 時,除非在PyImport_Inittab 表中有相關條目,否則不會自動呼叫PyInit_spam() 函式。要將模組加入初始化表,請使用PyImport_AppendInittab() 並在隨後選擇性地將該模組引入:

#define PY_SSIZE_T_CLEAN#include<Python.h>intmain(intargc,char*argv[]){PyStatusstatus;PyConfigconfig;PyConfig_InitPythonConfig(&config);/* 在 Py_Initialize 之前加入內建模組 */if(PyImport_AppendInittab("spam",PyInit_spam)==-1){fprintf(stderr,"Error: could not extend in-built modules table\n");exit(1);}/* 將 argv[0] 傳給 Python 直譯器 */status=PyConfig_SetBytesString(&config,&config.program_name,argv[0]);if(PyStatus_Exception(status)){gotoexception;}/* 初始化 Python 直譯器。這會是必要的。       如果此步驟失敗就會導致嚴重錯誤。*/status=Py_InitializeFromConfig(&config);if(PyStatus_Exception(status)){gotoexception;}PyConfig_Clear(&config);/* 可選擇引入模組;或者       可以延遲引入,直至嵌入式腳本       將其引入。*/PyObject*pmodule=PyImport_ImportModule("spam");if(!pmodule){PyErr_Print();fprintf(stderr,"Error: could not import module 'spam'\n");}// ... 在此使用 Python C API ...return0;exception:PyConfig_Clear(&config);Py_ExitStatusException(status);}

備註

sys.modules 中移除項目,或在一個行程中將已編譯模組引入到多個直譯器中(或在沒有exec() 介入的情況下使用fork())可能會對某些擴充模組造成問題。擴充模組作者在初始化內部資料結構時應特別小心。

Python 原始碼發行版本中包含了一個更實質的範例模組Modules/xxmodule.c。這個檔案可以當作模板使用,也可以簡單地當作範例來閱讀。

備註

不像我們的spam 範例,xxmodule 使用了多階段初始化 (multi-phase initialization)(Python 3.5 新增),其中的 PyModuleDef 結構會從PyInit_spam 回傳,而模組的建立則交由引入機制來完成。關於多階段初始化的詳細資訊請參閱PEP 489

1.5.Compilation and Linkage

There are two more things to do before you can use your new extension: compilingand linking it with the Python system. If you use dynamic loading, the detailsmay depend on the style of dynamic loading your system uses; see the chaptersabout building extension modules (chapter建立 C 與 C++ 擴充套件) and additionalinformation that pertains only to building on Windows (chapter建置 Windows 上的 C 和 C++ 擴充) for more information about this.

If you can't use dynamic loading, or if you want to make your module a permanentpart of the Python interpreter, you will have to change the configuration setupand rebuild the interpreter. Luckily, this is very simple on Unix: just placeyour file (spammodule.c for example) in theModules/ directoryof an unpacked source distribution, add a line to the fileModules/Setup.local describing your file:

spamspammodule.o

and rebuild the interpreter by runningmake in the topleveldirectory. You can also runmake in theModules/subdirectory, but then you must first rebuildMakefile there by running'make Makefile'. (This is necessary each time you change theSetup file.)

If your module requires additional libraries to link with, these can be listedon the line in the configuration file as well, for instance:

spamspammodule.o-lX11

1.6.Calling Python Functions from C

So far we have concentrated on making C functions callable from Python. Thereverse is also useful: calling Python functions from C. This is especially thecase for libraries that support so-called "callback" functions. If a Cinterface makes use of callbacks, the equivalent Python often needs to provide acallback mechanism to the Python programmer; the implementation will requirecalling the Python callback functions from a C callback. Other uses are alsoimaginable.

Fortunately, the Python interpreter is easily called recursively, and there is astandard interface to call a Python function. (I won't dwell on how to call thePython parser with a particular string as input --- if you're interested, have alook at the implementation of the-c command line option inModules/main.c from the Python source code.)

Calling a Python function is easy. First, the Python program must somehow passyou the Python function object. You should provide a function (or some otherinterface) to do this. When this function is called, save a pointer to thePython function object (be careful toPy_INCREF() it!) in a globalvariable --- or wherever you see fit. For example, the following function mightbe part of a module definition:

staticPyObject*my_callback=NULL;staticPyObject*my_set_callback(PyObject*dummy,PyObject*args){PyObject*result=NULL;PyObject*temp;if(PyArg_ParseTuple(args,"O:set_callback",&temp)){if(!PyCallable_Check(temp)){PyErr_SetString(PyExc_TypeError,"parameter must be callable");returnNULL;}Py_XINCREF(temp);/* Add a reference to new callback */Py_XDECREF(my_callback);/* Dispose of previous callback */my_callback=temp;/* Remember new callback *//* Boilerplate to return "None" */Py_INCREF(Py_None);result=Py_None;}returnresult;}

This function must be registered with the interpreter using theMETH_VARARGS flag; this is described in section模組的方法表和初始化函式. ThePyArg_ParseTuple() function and its arguments are documented in sectionExtracting Parameters in Extension Functions.

The macrosPy_XINCREF() andPy_XDECREF() increment/decrement thereference count of an object and are safe in the presence ofNULL pointers(but note thattemp will not beNULL in this context). More info on themin sectionReference Counts.

Later, when it is time to call the function, you call the C functionPyObject_CallObject(). This function has two arguments, both pointers toarbitrary Python objects: the Python function, and the argument list. Theargument list must always be a tuple object, whose length is the number ofarguments. To call the Python function with no arguments, pass inNULL, oran empty tuple; to call it with one argument, pass a singleton tuple.Py_BuildValue() returns a tuple when its format string consists of zeroor more format codes between parentheses. For example:

intarg;PyObject*arglist;PyObject*result;...arg=123;.../* Time to call the callback */arglist=Py_BuildValue("(i)",arg);result=PyObject_CallObject(my_callback,arglist);Py_DECREF(arglist);

PyObject_CallObject() returns a Python object pointer: this is the returnvalue of the Python function.PyObject_CallObject() is"reference-count-neutral" with respect to its arguments. In the example a newtuple was created to serve as the argument list, which isPy_DECREF()-ed immediately after thePyObject_CallObject()call.

The return value ofPyObject_CallObject() is "new": either it is a brandnew object, or it is an existing object whose reference count has beenincremented. So, unless you want to save it in a global variable, you shouldsomehowPy_DECREF() the result, even (especially!) if you are notinterested in its value.

Before you do this, however, it is important to check that the return valueisn'tNULL. If it is, the Python function terminated by raising an exception.If the C code that calledPyObject_CallObject() is called from Python, itshould now return an error indication to its Python caller, so the interpretercan print a stack trace, or the calling Python code can handle the exception.If this is not possible or desirable, the exception should be cleared by callingPyErr_Clear(). For example:

if(result==NULL)returnNULL;/* Pass error back */...useresult...Py_DECREF(result);

Depending on the desired interface to the Python callback function, you may alsohave to provide an argument list toPyObject_CallObject(). In some casesthe argument list is also provided by the Python program, through the sameinterface that specified the callback function. It can then be saved and usedin the same manner as the function object. In other cases, you may have toconstruct a new tuple to pass as the argument list. The simplest way to do thisis to callPy_BuildValue(). For example, if you want to pass an integralevent code, you might use the following code:

PyObject*arglist;...arglist=Py_BuildValue("(l)",eventcode);result=PyObject_CallObject(my_callback,arglist);Py_DECREF(arglist);if(result==NULL)returnNULL;/* Pass error back *//* Here maybe use the result */Py_DECREF(result);

Note the placement ofPy_DECREF(arglist) immediately after the call, beforethe error check! Also note that strictly speaking this code is not complete:Py_BuildValue() may run out of memory, and this should be checked.

You may also call a function with keyword arguments by usingPyObject_Call(), which supports arguments and keyword arguments. As inthe above example, we usePy_BuildValue() to construct the dictionary.

PyObject*dict;...dict=Py_BuildValue("{s:i}","name",val);result=PyObject_Call(my_callback,NULL,dict);Py_DECREF(dict);if(result==NULL)returnNULL;/* Pass error back *//* Here maybe use the result */Py_DECREF(result);

1.7.Extracting Parameters in Extension Functions

ThePyArg_ParseTuple() function is declared as follows:

intPyArg_ParseTuple(PyObject*arg,constchar*format,...);

Thearg argument must be a tuple object containing an argument list passedfrom Python to a C function. Theformat argument must be a format string,whose syntax is explained in剖析引數與建置數值 in the Python/C API ReferenceManual. The remaining arguments must be addresses of variables whose type isdetermined by the format string.

Note that whilePyArg_ParseTuple() checks that the Python arguments havethe required types, it cannot check the validity of the addresses of C variablespassed to the call: if you make mistakes there, your code will probably crash orat least overwrite random bits in memory. So be careful!

Note that any Python object references which are provided to the caller areborrowed references; do not decrement their reference count!

一些呼叫範例:

#define PY_SSIZE_T_CLEAN#include<Python.h>
intok;inti,j;longk,l;constchar*s;Py_ssize_tsize;ok=PyArg_ParseTuple(args,"");/* 沒有引數 *//* Python 呼叫:f() */
ok=PyArg_ParseTuple(args,"s",&s);/* A string *//* Possible Python call: f('whoops!') */
ok=PyArg_ParseTuple(args,"lls",&k,&l,&s);/* Two longs and a string *//* Possible Python call: f(1, 2, 'three') */
ok=PyArg_ParseTuple(args,"(ii)s#",&i,&j,&s,&size);/* A pair of ints and a string, whose size is also returned *//* Possible Python call: f((1, 2), 'three') */
{constchar*file;constchar*mode="r";intbufsize=0;ok=PyArg_ParseTuple(args,"s|si",&file,&mode,&bufsize);/* A string, and optionally another string and an integer *//* Possible Python calls:       f('spam')       f('spam', 'w')       f('spam', 'wb', 100000) */}
{intleft,top,right,bottom,h,v;ok=PyArg_ParseTuple(args,"((ii)(ii))(ii)",&left,&top,&right,&bottom,&h,&v);/* A rectangle and a point *//* Possible Python call:       f(((0, 0), (400, 300)), (10, 10)) */}
{Py_complexc;ok=PyArg_ParseTuple(args,"D:myfunction",&c);/* a complex, also providing a function name for errors *//* Possible Python call: myfunction(1+2j) */}

1.8.Keyword Parameters for Extension Functions

ThePyArg_ParseTupleAndKeywords() function is declared as follows:

intPyArg_ParseTupleAndKeywords(PyObject*arg,PyObject*kwdict,constchar*format,char*const*kwlist,...);

Thearg andformat parameters are identical to those of thePyArg_ParseTuple() function. Thekwdict parameter is the dictionary ofkeywords received as the third parameter from the Python runtime. Thekwlistparameter is aNULL-terminated list of strings which identify the parameters;the names are matched with the type information fromformat from left toright. On success,PyArg_ParseTupleAndKeywords() returns true, otherwiseit returns false and raises an appropriate exception.

備註

Nested tuples cannot be parsed when using keyword arguments! Keyword parameterspassed in which are not present in thekwlist will causeTypeError tobe raised.

Here is an example module which uses keywords, based on an example by GeoffPhilbrick (philbrick@hks.com):

#define PY_SSIZE_T_CLEAN#include<Python.h>staticPyObject*keywdarg_parrot(PyObject*self,PyObject*args,PyObject*keywds){intvoltage;constchar*state="a stiff";constchar*action="voom";constchar*type="Norwegian Blue";staticchar*kwlist[]={"voltage","state","action","type",NULL};if(!PyArg_ParseTupleAndKeywords(args,keywds,"i|sss",kwlist,&voltage,&state,&action,&type))returnNULL;printf("-- This parrot wouldn't %s if you put %i Volts through it.\n",action,voltage);printf("-- Lovely plumage, the %s -- It's %s!\n",type,state);Py_RETURN_NONE;}staticPyMethodDefkeywdarg_methods[]={/* The cast of the function is necessary since PyCFunction values     * only take two PyObject* parameters, and keywdarg_parrot() takes     * three.     */{"parrot",(PyCFunction)(void(*)(void))keywdarg_parrot,METH_VARARGS|METH_KEYWORDS,"Print a lovely skit to standard output."},{NULL,NULL,0,NULL}/* sentinel */};staticstructPyModuleDefkeywdargmodule={PyModuleDef_HEAD_INIT,"keywdarg",NULL,-1,keywdarg_methods};PyMODINIT_FUNCPyInit_keywdarg(void){returnPyModule_Create(&keywdargmodule);}

1.9.Building Arbitrary Values

This function is the counterpart toPyArg_ParseTuple(). It is declaredas follows:

PyObject*Py_BuildValue(constchar*format,...);

It recognizes a set of format units similar to the ones recognized byPyArg_ParseTuple(), but the arguments (which are input to the function,not output) must not be pointers, just values. It returns a new Python object,suitable for returning from a C function called from Python.

One difference withPyArg_ParseTuple(): while the latter requires itsfirst argument to be a tuple (since Python argument lists are always representedas tuples internally),Py_BuildValue() does not always build a tuple. Itbuilds a tuple only if its format string contains two or more format units. Ifthe format string is empty, it returnsNone; if it contains exactly oneformat unit, it returns whatever object is described by that format unit. Toforce it to return a tuple of size 0 or one, parenthesize the format string.

Examples (to the left the call, to the right the resulting Python value):

Py_BuildValue("")                        NonePy_BuildValue("i", 123)                  123Py_BuildValue("iii", 123, 456, 789)      (123, 456, 789)Py_BuildValue("s", "hello")              'hello'Py_BuildValue("y", "hello")              b'hello'Py_BuildValue("ss", "hello", "world")    ('hello', 'world')Py_BuildValue("s#", "hello", 4)          'hell'Py_BuildValue("y#", "hello", 4)          b'hell'Py_BuildValue("()")                      ()Py_BuildValue("(i)", 123)                (123,)Py_BuildValue("(ii)", 123, 456)          (123, 456)Py_BuildValue("(i,i)", 123, 456)         (123, 456)Py_BuildValue("[i,i]", 123, 456)         [123, 456]Py_BuildValue("{s:i,s:i}",              "abc", 123, "def", 456)    {'abc': 123, 'def': 456}Py_BuildValue("((ii)(ii)) (ii)",              1, 2, 3, 4, 5, 6)          (((1, 2), (3, 4)), (5, 6))

1.10.Reference Counts

In languages like C or C++, the programmer is responsible for dynamic allocationand deallocation of memory on the heap. In C, this is done using the functionsmalloc() andfree(). In C++, the operatorsnew anddelete are used with essentially the same meaning and we'll restrictthe following discussion to the C case.

Every block of memory allocated withmalloc() should eventually bereturned to the pool of available memory by exactly one call tofree().It is important to callfree() at the right time. If a block's addressis forgotten butfree() is not called for it, the memory it occupiescannot be reused until the program terminates. This is called amemoryleak. On the other hand, if a program callsfree() for a block and thencontinues to use the block, it creates a conflict with reuse of the blockthrough anothermalloc() call. This is calledusing freed memory.It has the same bad consequences as referencing uninitialized data --- coredumps, wrong results, mysterious crashes.

Common causes of memory leaks are unusual paths through the code. For instance,a function may allocate a block of memory, do some calculation, and then freethe block again. Now a change in the requirements for the function may add atest to the calculation that detects an error condition and can returnprematurely from the function. It's easy to forget to free the allocated memoryblock when taking this premature exit, especially when it is added later to thecode. Such leaks, once introduced, often go undetected for a long time: theerror exit is taken only in a small fraction of all calls, and most modernmachines have plenty of virtual memory, so the leak only becomes apparent in along-running process that uses the leaking function frequently. Therefore, it'simportant to prevent leaks from happening by having a coding convention orstrategy that minimizes this kind of errors.

Since Python makes heavy use ofmalloc() andfree(), it needs astrategy to avoid memory leaks as well as the use of freed memory. The chosenmethod is calledreference counting. The principle is simple: everyobject contains a counter, which is incremented when a reference to the objectis stored somewhere, and which is decremented when a reference to it is deleted.When the counter reaches zero, the last reference to the object has been deletedand the object is freed.

An alternative strategy is calledautomatic garbage collection.(Sometimes, reference counting is also referred to as a garbage collectionstrategy, hence my use of "automatic" to distinguish the two.) The bigadvantage of automatic garbage collection is that the user doesn't need to callfree() explicitly. (Another claimed advantage is an improvement in speedor memory usage --- this is no hard fact however.) The disadvantage is that forC, there is no truly portable automatic garbage collector, while referencecounting can be implemented portably (as long as the functionsmalloc()andfree() are available --- which the C Standard guarantees). Maybe someday a sufficiently portable automatic garbage collector will be available for C.Until then, we'll have to live with reference counts.

While Python uses the traditional reference counting implementation, it alsooffers a cycle detector that works to detect reference cycles. This allowsapplications to not worry about creating direct or indirect circular references;these are the weakness of garbage collection implemented using only referencecounting. Reference cycles consist of objects which contain (possibly indirect)references to themselves, so that each object in the cycle has a reference countwhich is non-zero. Typical reference counting implementations are not able toreclaim the memory belonging to any objects in a reference cycle, or referencedfrom the objects in the cycle, even though there are no further references tothe cycle itself.

The cycle detector is able to detect garbage cycles and can reclaim them.Thegc module exposes a way to run the detector (thecollect() function), as well as configurationinterfaces and the ability to disable the detector at runtime.

1.10.1.Reference Counting in Python

There are two macros,Py_INCREF(x) andPy_DECREF(x), which handle theincrementing and decrementing of the reference count.Py_DECREF() alsofrees the object when the count reaches zero. For flexibility, it doesn't callfree() directly --- rather, it makes a call through a function pointer inthe object'stype object. For this purpose (and others), every objectalso contains a pointer to its type object.

The big question now remains: when to usePy_INCREF(x) andPy_DECREF(x)?Let's first introduce some terms. Nobody "owns" an object; however, you canown a reference to an object. An object's reference count is now definedas the number of owned references to it. The owner of a reference isresponsible for callingPy_DECREF() when the reference is no longerneeded. Ownership of a reference can be transferred. There are three ways todispose of an owned reference: pass it on, store it, or callPy_DECREF().Forgetting to dispose of an owned reference creates a memory leak.

It is also possible toborrow[2] a reference to an object. Theborrower of a reference should not callPy_DECREF(). The borrower mustnot hold on to the object longer than the owner from which it was borrowed.Using a borrowed reference after the owner has disposed of it risks using freedmemory and should be avoided completely[3].

The advantage of borrowing over owning a reference is that you don't need totake care of disposing of the reference on all possible paths through the code--- in other words, with a borrowed reference you don't run the risk of leakingwhen a premature exit is taken. The disadvantage of borrowing over owning isthat there are some subtle situations where in seemingly correct code a borrowedreference can be used after the owner from which it was borrowed has in factdisposed of it.

A borrowed reference can be changed into an owned reference by callingPy_INCREF(). This does not affect the status of the owner from which thereference was borrowed --- it creates a new owned reference, and gives fullowner responsibilities (the new owner must dispose of the reference properly, aswell as the previous owner).

1.10.2.Ownership Rules

Whenever an object reference is passed into or out of a function, it is part ofthe function's interface specification whether ownership is transferred with thereference or not.

Most functions that return a reference to an object pass on ownership with thereference. In particular, all functions whose function it is to create a newobject, such asPyLong_FromLong() andPy_BuildValue(), passownership to the receiver. Even if the object is not actually new, you stillreceive ownership of a new reference to that object. For instance,PyLong_FromLong() maintains a cache of popular values and can return areference to a cached item.

Many functions that extract objects from other objects also transfer ownershipwith the reference, for instancePyObject_GetAttrString(). The pictureis less clear, here, however, since a few common routines are exceptions:PyTuple_GetItem(),PyList_GetItem(),PyDict_GetItem(), andPyDict_GetItemString() all return references that you borrow from thetuple, list or dictionary.

The functionPyImport_AddModule() also returns a borrowed reference, eventhough it may actually create the object it returns: this is possible because anowned reference to the object is stored insys.modules.

When you pass an object reference into another function, in general, thefunction borrows the reference from you --- if it needs to store it, it will usePy_INCREF() to become an independent owner. There are exactly twoimportant exceptions to this rule:PyTuple_SetItem() andPyList_SetItem(). These functions take over ownership of the item passedto them --- even if they fail! (Note thatPyDict_SetItem() and friendsdon't take over ownership --- they are "normal.")

When a C function is called from Python, it borrows references to its argumentsfrom the caller. The caller owns a reference to the object, so the borrowedreference's lifetime is guaranteed until the function returns. Only when such aborrowed reference must be stored or passed on, it must be turned into an ownedreference by callingPy_INCREF().

The object reference returned from a C function that is called from Python mustbe an owned reference --- ownership is transferred from the function to itscaller.

1.10.3.Thin Ice

There are a few situations where seemingly harmless use of a borrowed referencecan lead to problems. These all have to do with implicit invocations of theinterpreter, which can cause the owner of a reference to dispose of it.

The first and most important case to know about is usingPy_DECREF() onan unrelated object while borrowing a reference to a list item. For instance:

voidbug(PyObject*list){PyObject*item=PyList_GetItem(list,0);PyList_SetItem(list,1,PyLong_FromLong(0L));PyObject_Print(item,stdout,0);/* BUG! */}

This function first borrows a reference tolist[0], then replaceslist[1] with the value0, and finally prints the borrowed reference.Looks harmless, right? But it's not!

Let's follow the control flow intoPyList_SetItem(). The list ownsreferences to all its items, so when item 1 is replaced, it has to dispose ofthe original item 1. Now let's suppose the original item 1 was an instance of auser-defined class, and let's further suppose that the class defined a__del__() method. If this class instance has a reference count of 1,disposing of it will call its__del__() method.

Since it is written in Python, the__del__() method can execute arbitraryPython code. Could it perhaps do something to invalidate the reference toitem inbug()? You bet! Assuming that the list passed intobug() is accessible to the__del__() method, it could execute astatement to the effect ofdellist[0], and assuming this was the lastreference to that object, it would free the memory associated with it, therebyinvalidatingitem.

The solution, once you know the source of the problem, is easy: temporarilyincrement the reference count. The correct version of the function reads:

voidno_bug(PyObject*list){PyObject*item=PyList_GetItem(list,0);Py_INCREF(item);PyList_SetItem(list,1,PyLong_FromLong(0L));PyObject_Print(item,stdout,0);Py_DECREF(item);}

This is a true story. An older version of Python contained variants of this bugand someone spent a considerable amount of time in a C debugger to figure outwhy his__del__() methods would fail...

The second case of problems with a borrowed reference is a variant involvingthreads. Normally, multiple threads in the Python interpreter can't get in eachother's way, because there is a global lock protecting Python's entire objectspace. However, it is possible to temporarily release this lock using the macroPy_BEGIN_ALLOW_THREADS, and to re-acquire it usingPy_END_ALLOW_THREADS. This is common around blocking I/O calls, tolet other threads use the processor while waiting for the I/O to complete.Obviously, the following function has the same problem as the previous one:

voidbug(PyObject*list){PyObject*item=PyList_GetItem(list,0);Py_BEGIN_ALLOW_THREADS...someblockingI/Ocall...Py_END_ALLOW_THREADSPyObject_Print(item,stdout,0);/* BUG! */}

1.10.4.NULL 指標

In general, functions that take object references as arguments do not expect youto pass themNULL pointers, and will dump core (or cause later core dumps) ifyou do so. Functions that return object references generally returnNULL onlyto indicate that an exception occurred. The reason for not testing forNULLarguments is that functions often pass the objects they receive on to otherfunction --- if each function were to test forNULL, there would be a lot ofredundant tests and the code would run more slowly.

It is better to test forNULL only at the "source:" when a pointer that may beNULL is received, for example, frommalloc() or from a function thatmay raise an exception.

The macrosPy_INCREF() andPy_DECREF() do not check forNULLpointers --- however, their variantsPy_XINCREF() andPy_XDECREF()do.

The macros for checking for a particular object type (Pytype_Check()) don'tcheck forNULL pointers --- again, there is much code that calls several ofthese in a row to test an object against various different expected types, andthis would generate redundant tests. There are no variants withNULLchecking.

The C function calling mechanism guarantees that the argument list passed to Cfunctions (args in the examples) is neverNULL --- in fact it guaranteesthat it is always a tuple[4].

It is a severe error to ever let aNULL pointer "escape" to the Python user.

1.11.Writing Extensions in C++

It is possible to write extension modules in C++. Some restrictions apply. Ifthe main program (the Python interpreter) is compiled and linked by the Ccompiler, global or static objects with constructors cannot be used. This isnot a problem if the main program is linked by the C++ compiler. Functions thatwill be called by the Python interpreter (in particular, module initializationfunctions) have to be declared usingextern"C". It is unnecessary toenclose the Python header files inextern"C"{...} --- they use this formalready if the symbol__cplusplus is defined (all recent C++ compilersdefine this symbol).

1.12.Providing a C API for an Extension Module

Many extension modules just provide new functions and types to be used fromPython, but sometimes the code in an extension module can be useful for otherextension modules. For example, an extension module could implement a type"collection" which works like lists without order. Just like the standard Pythonlist type has a C API which permits extension modules to create and manipulatelists, this new collection type should have a set of C functions for directmanipulation from other extension modules.

At first sight this seems easy: just write the functions (without declaring themstatic, of course), provide an appropriate header file, and documentthe C API. And in fact this would work if all extension modules were alwayslinked statically with the Python interpreter. When modules are used as sharedlibraries, however, the symbols defined in one module may not be visible toanother module. The details of visibility depend on the operating system; somesystems use one global namespace for the Python interpreter and all extensionmodules (Windows, for example), whereas others require an explicit list ofimported symbols at module link time (AIX is one example), or offer a choice ofdifferent strategies (most Unices). And even if symbols are globally visible,the module whose functions one wishes to call might not have been loaded yet!

Portability therefore requires not to make any assumptions about symbolvisibility. This means that all symbols in extension modules should be declaredstatic, except for the module's initialization function, in order toavoid name clashes with other extension modules (as discussed in section模組的方法表和初始化函式). And it means that symbols thatshould be accessible fromother extension modules must be exported in a different way.

Python provides a special mechanism to pass C-level information (pointers) fromone extension module to another one: Capsules. A Capsule is a Python data typewhich stores a pointer (void*). Capsules can only be created andaccessed via their C API, but they can be passed around like any other Pythonobject. In particular, they can be assigned to a name in an extension module'snamespace. Other extension modules can then import this module, retrieve thevalue of this name, and then retrieve the pointer from the Capsule.

There are many ways in which Capsules can be used to export the C API of anextension module. Each function could get its own Capsule, or all C API pointerscould be stored in an array whose address is published in a Capsule. And thevarious tasks of storing and retrieving the pointers can be distributed indifferent ways between the module providing the code and the client modules.

Whichever method you choose, it's important to name your Capsules properly.The functionPyCapsule_New() takes a name parameter(constchar*); you're permitted to pass in aNULL name, butwe strongly encourage you to specify a name. Properly named Capsules providea degree of runtime type-safety; there is no feasible way to tell one unnamedCapsule from another.

In particular, Capsules used to expose C APIs should be given a name followingthis convention:

modulename.attributename

The convenience functionPyCapsule_Import() makes it easy toload a C API provided via a Capsule, but only if the Capsule's namematches this convention. This behavior gives C API users a high degreeof certainty that the Capsule they load contains the correct C API.

The following example demonstrates an approach that puts most of the burden onthe writer of the exporting module, which is appropriate for commonly usedlibrary modules. It stores all C API pointers (just one in the example!) in anarray ofvoid pointers which becomes the value of a Capsule. The headerfile corresponding to the module provides a macro that takes care of importingthe module and retrieving its C API pointers; client modules only have to callthis macro before accessing the C API.

The exporting module is a modification of thespam module from section一個簡單範例. The functionspam.system() does not callthe C library functionsystem() directly, but a functionPySpam_System(), which would of course do something more complicated inreality (such as adding "spam" to every command). This functionPySpam_System() is also exported to other extension modules.

The functionPySpam_System() is a plain C function, declaredstatic like everything else:

staticintPySpam_System(constchar*command){returnsystem(command);}

The functionspam_system() is modified in a trivial way:

staticPyObject*spam_system(PyObject*self,PyObject*args){constchar*command;intsts;if(!PyArg_ParseTuple(args,"s",&command))returnNULL;sts=PySpam_System(command);returnPyLong_FromLong(sts);}

In the beginning of the module, right after the line

#include<Python.h>

two more lines must be added:

#define SPAM_MODULE#include"spammodule.h"

The#define is used to tell the header file that it is being included in theexporting module, not a client module. Finally, the module's initializationfunction must take care of initializing the C API pointer array:

PyMODINIT_FUNCPyInit_spam(void){PyObject*m;staticvoid*PySpam_API[PySpam_API_pointers];PyObject*c_api_object;m=PyModule_Create(&spammodule);if(m==NULL)returnNULL;/* Initialize the C API pointer array */PySpam_API[PySpam_System_NUM]=(void*)PySpam_System;/* Create a Capsule containing the API pointer array's address */c_api_object=PyCapsule_New((void*)PySpam_API,"spam._C_API",NULL);if(PyModule_Add(m,"_C_API",c_api_object)<0){Py_DECREF(m);returnNULL;}returnm;}

Note thatPySpam_API is declaredstatic; otherwise the pointerarray would disappear whenPyInit_spam() terminates!

The bulk of the work is in the header filespammodule.h, which lookslike this:

#ifndef Py_SPAMMODULE_H#define Py_SPAMMODULE_H#ifdef __cplusplusextern"C"{#endif/* Header file for spammodule *//* C API functions */#define PySpam_System_NUM 0#define PySpam_System_RETURN int#define PySpam_System_PROTO (const char *command)/* Total number of C API pointers */#define PySpam_API_pointers 1#ifdef SPAM_MODULE/* This section is used when compiling spammodule.c */staticPySpam_System_RETURNPySpam_SystemPySpam_System_PROTO;#else/* This section is used in modules that use spammodule's API */staticvoid**PySpam_API;#define PySpam_System \ (*(PySpam_System_RETURN (*)PySpam_System_PROTO) PySpam_API[PySpam_System_NUM])/* Return -1 on error, 0 on success. * PyCapsule_Import will set an exception if there's an error. */staticintimport_spam(void){PySpam_API=(void**)PyCapsule_Import("spam._C_API",0);return(PySpam_API!=NULL)?0:-1;}#endif#ifdef __cplusplus}#endif#endif/* !defined(Py_SPAMMODULE_H) */

All that a client module must do in order to have access to the functionPySpam_System() is to call the function (or rather macro)import_spam() in its initialization function:

PyMODINIT_FUNCPyInit_client(void){PyObject*m;m=PyModule_Create(&clientmodule);if(m==NULL)returnNULL;if(import_spam()<0)returnNULL;/* additional initialization can happen here */returnm;}

The main disadvantage of this approach is that the filespammodule.h israther complicated. However, the basic structure is the same for each functionthat is exported, so it has to be learned only once.

Finally it should be mentioned that Capsules offer additional functionality,which is especially useful for memory allocation and deallocation of the pointerstored in a Capsule. The details are described in the Python/C API ReferenceManual in the sectionCapsules and in the implementation of Capsules (filesInclude/pycapsule.h andObjects/pycapsule.c in the Python sourcecode distribution).

註腳

[1]

An interface for this function already exists in the standard moduleos--- it was chosen as a simple and straightforward example.

[2]

The metaphor of "borrowing" a reference is not completely correct: the ownerstill has a copy of the reference.

[3]

Checking that the reference count is at least 1does not work --- thereference count itself could be in freed memory and may thus be reused foranother object!

[4]

These guarantees don't hold when you use the "old" style calling convention ---this is still found in much existing code.