如何進(jìn)行處理Python對(duì)象參數(shù)解析
在Python對(duì)象中使用C語(yǔ)言編寫的擴(kuò)展模塊,必須將其編譯成動(dòng)態(tài)鏈接庫(kù)的形式,通常使用Python的C語(yǔ)言擴(kuò)展接口提供的函數(shù)PyArg_ParseTuple()來(lái)獲得這些參數(shù)值,希望本文能夠?qū)Υ蠹矣袔椭?/FONT>
Python是用C語(yǔ)言實(shí)現(xiàn)的一種腳本語(yǔ)言,本身具有優(yōu)良的開(kāi)放性和可擴(kuò)展性,并提供了方便靈活的應(yīng)用程序接口(API)。從而使得C/C++程序員能夠在各個(gè)級(jí)別上對(duì)Python解釋器的功能進(jìn)行擴(kuò)展。在使用C/C++對(duì)Python進(jìn)行功能擴(kuò)展之前,必須首先掌握Python解釋所提供的C語(yǔ)言接口。
Python是一門面向?qū)ο蟮哪_本語(yǔ)言,所有的對(duì)象在Python解釋器中都被表示成PyObject,PyObject結(jié)構(gòu)包含Python對(duì)象的所有成員指針。并且對(duì)Python對(duì)象的類型信息和引用計(jì)數(shù)進(jìn)行維護(hù)。在進(jìn)行Python的擴(kuò)展編程時(shí),一旦要在C或者C++中對(duì)Python對(duì)象進(jìn)行處理,就意味著要維護(hù)一個(gè)PyObject結(jié)構(gòu)。
在Python的C語(yǔ)言擴(kuò)展接口中,大部分函數(shù)都有一個(gè)或者多個(gè)參數(shù)為PyObject指針類型,并且返回值也大都為PyObject指針。為了簡(jiǎn)化內(nèi)存管理,Python通過(guò)引用計(jì)數(shù)機(jī)制實(shí)現(xiàn)了自動(dòng)的垃圾回收功能,Python中的每個(gè)對(duì)象都有一個(gè)引用計(jì)數(shù)。
用來(lái)計(jì)數(shù)該對(duì)象在不同場(chǎng)所分別被引用了多少次。每當(dāng)引用一次Python對(duì)象,相應(yīng)的引用計(jì)數(shù)就增1,每當(dāng)消毀一次Python對(duì)象,則相應(yīng)的引用就減1,只有當(dāng)引用計(jì)數(shù)為零時(shí),才真正從內(nèi)存中刪除Python對(duì)象。
下面的例子說(shuō)明了Python解釋器如何利用引用計(jì)數(shù)來(lái)對(duì)Pyhon對(duì)象進(jìn)行管理:
- #include <Python.h>
- PyObject* wrap_fact(PyObject* self, PyObject* args)
- {
- int n, result;
- if (! PyArg_ParseTuple(args, "i:fact", &n))
- return NULL;
- result = fact(n);
- return Py_BuildValue("i", result);
- }
- static PyMethodDef exampleMethods[] =
- {
- {"fact", wrap_fact, METH_VARARGS, "Caculate N!"},
- {NULL, NULL}
- };
- void initexample()
- {
- PyObject* m;
- m = Py_InitModule("example", exampleMethods);
- }
在C/C++中處理Python對(duì)象時(shí),對(duì)引用計(jì)數(shù)進(jìn)行正確的維護(hù)是一個(gè)關(guān)鍵問(wèn)題,處理不好將很容易產(chǎn)生內(nèi)存泄漏。Python的C語(yǔ)言接口提供了一些宏來(lái)對(duì)引用計(jì)數(shù)進(jìn)行維護(hù),最常見(jiàn)的是用Py_INCREF()來(lái)增加使Python對(duì)象的引用計(jì)數(shù)增1,用Py_DECREF()來(lái)使Python對(duì)象的引用計(jì)數(shù)減1。
該函數(shù)是Python解釋器和C函數(shù)進(jìn)行交互的接口,帶有兩個(gè)參數(shù):self和args。參數(shù)self只在C函數(shù)被實(shí)現(xiàn)為內(nèi)聯(lián)方法(built-in method)時(shí)才被用到。通常該參數(shù)的值為空(NULL),參數(shù)args中包含了Python解釋器要傳遞給C函數(shù)的所有參數(shù),通常使用Python的C語(yǔ)言擴(kuò)展接口提供的函數(shù)PyArg_ParseTuple()來(lái)獲得這些參數(shù)值。
方法列表中的每項(xiàng)由四個(gè)部分組成:方法名、導(dǎo)出函數(shù)、參數(shù)傳遞方式和方法描述。方法名是從Python解釋器中調(diào)用該方法時(shí)所使用的名字。參數(shù)傳遞方式則規(guī)定了Python向C函數(shù)傳遞參數(shù)的具體形式,可選的兩種方式是METH_VARARGS和METH_KEYWORDS。
其中METH_VARARGS是參數(shù)傳遞的標(biāo)準(zhǔn)形式,它通過(guò)Python的元組在Python解釋器和C函數(shù)之間傳遞參數(shù),若采用METH_KEYWORD方式,則Python解釋器和C函數(shù)之間將通過(guò)Python的字典類型在兩者之間進(jìn)行參數(shù)傳遞。
【編輯推薦】