pythonc C擴充套件Python

2021-10-11 21:50:59 字數 4647 閱讀 4976

使用c擴充套件python

pyerr_*()函式是將乙個異常物件壓入到python直譯器的異常棧中

pyerr_clear()函式是將python異常棧中棧頂的元素彈出, 呼叫這個函式通常就相當於在python程式中的try: except: 語句中except的作用

python中的api, 每乙個模組對應的api是pymodname_funcinmod()

python擴充套件模組的函式模板:

// first

static pyobject *exfunc(pyobject *self, pyobject *args) is the symbol of the end of pymethoddef array, python interpretor will stop walking

this pymethoddef array when meeting it.

according to the official:

when using only meth_varargs, the function should expect the python-level parameters to be passed in as a tuple

acceptable for parsing via pyarg_parsetuple()

,// third

static struct pymoduledef exmodule = ",

"abc", 123, "def", 456)

py_buildvalue("((ii)(ii)) (ii)",

1, 2, 3, 4, 5, 6) (((1, 2), (3, 4)), (5, 6))

我們知道python知道用特定的py_init, 他是如何實現的呢, 其實使用了巨集中的#, 在巨集定義中,使用 # 將引數轉為字串

如果是借來的引用的話, 是不會增加該物件的引用計數的, 但是在借來的基礎上, 使用py_increase增加它的引用計數, 可以把借來的轉為自己持有的

幾乎所有的python建立pyobject物件的api都會返回乙個擁有的引用, 同時大多數的從乙個物件中取出另乙個物件的函式api也都是擁有的引用, 例外的pytuple_getitem(), pylist_getitem(), pydict_getitem(), pyimport_addmodule() and pydict_getitemstring()等函式則是返回借來的物件

傳入引數到python的api中, 大多數的引數物件都是不會增加引用的, 但是pytuple_setitem() and pylist_setitem()是例外

對24和25的補充, 使用借來的引用, 它的存活週期是乙個pythoncfunction, 如果需要物件存起來的話, 就會調動py_increase增加引用計數, 但是如果要返回乙個python物件的話, 需要增加其引用計數

一般pythonapi不怎麼檢驗python物件為null的情況

模組的一些初始化操作在pyinit_函式中進行

如果希望新增新的內建型別, 這個我最熟悉(那是多麼痛的領悟), 因為我寫過, 定義乙個type型別結構體, 第乙個是pyobject_head, 接著在初始化type(一定要有.tp_flags = py_tpflags_default,), 在pyinit_中將該型別新增到模組物件中

在擴充套件模組中設定的名稱為modulename.subname

if (pytype_ready(&customtype) < 0)

return;

this adds the type to the module dictionary.

pymodule_addobject(m, "custom", (pyobject *) &customtype);

乙個完整的type賦值, 根據1, 2, 3得知, 為什麼每次建立乙個型別都會有new, init, del, 因為在其對應的pytypeobject中需要指明, 並且不是通過pymethoddef表控制的

static pytypeobject customtype = sublistobject;

static pyobject *

sublist_increment(sublistobject *self, pyobject *unused)

self->state++;

return pylong_fromlong(self->state);

static pymethoddef sublist_methods = ,

,static int

sublist_init(sublistobject *self, pyobject *args, pyobject *kwds)

if (pylist_type.tp_init((pyobject *) self, args, kwds) < 0)

return -1;

self->state = 0;

return 0;

static pytypeobject sublisttype = customobject;

static void

custom_dealloc(customobject *self)

py_xdecref(self->first);

py_xdecref(self->last);

py_type(self)->tp_free((pyobject *) self);

static pyobject *

custom_new(pytypeobject *type, pyobject *args, pyobject *kwds)

customobject *self;

self = (customobject *) type->tp_alloc(type, 0);

if (self != null) ;

pyobject *first = null, *last = null, *tmp;

if (!pyarg_parsetupleandkeywords(args, kwds, "|uui", kwlist,

&first, &last,

&self->number))

return -1;

if (first) ,

/* sentinel */

static pyobject *

custom_getfirst(customobject *self, void *closure)

py_incref(self->first);

return self->first;

static int

custom_setfirst(customobject *self, pyobject *value, void *closure)

pyobject *tmp;

if (value == null) ,

, /* sentinel */

static pyobject *

custom_name(customobject *self, pyobject *py_unused(ignored))

return pyunicode_fromformat("%s %s", self->first, self->last);

static pymethoddef custom_methods = /* sentinel */

static pytypeobject customtype = {

pyvarobject_head_init(null, 0)

.tp_name = "custom3.custom",

.tp_doc = "custom objects",

.tp_basicsize = sizeof(customobject),

.tp_itemsize = 0,

.tp_flags = py_tpflags_default | py_tpflags_basetype,

.tp_new = custom_new,

.tp_init = (initproc) custom_init,

.tp_dealloc = (destructor) custom_dealloc,

.tp_members = custom_members,

.tp_methods = custom_methods,

.tp_getset = custom_getsetters,

static pymoduledef custommodule = {

pymoduledef_head_init,

.m_name = "custom3",

.m_doc = "example module that creates an extension type.",

.m_size = -1,

pymodinit_func

pyinit_custom3(void)

pyobject *m;

if (pytype_ready(&customtype) < 0)

return null;

m = pymodule_create(&custommodule);

if (m == null)

return null;

py_incref(&customtype);

pymodule_addobject(m, "custom", (pyobject *) &customtype);

return m;

python c c 二進位制檔案讀寫

只討論二進位制檔案的讀寫。以二進位制的形式開啟檔案 with open filename wb as fd do with fd fd.write strobject 二進位制strobject寫入檔案 fd.read byte len 讀取byte len位元組資料wb 表示以二進位制寫的方式開啟...

protocol buffer在python中使用

2.然後將potoc 3.0.0 win32.zip下 檔案 protoc.exe,放到protobuf python 3.0.0 protobuf 3.0.0 src中,在cmd 下在資料夾protobuf python 3.0.0 protobuf 3.0.0 python下依次執行 pytho...

pytho學習旅途

轉換當前格式日期 dt datetime.datetime.strptime dtstr,y m d print dt 切片獲取年份 輸入一行字元,分別統計其中英文本母,空格,數,和其他字元數 import string s ww m 23 4j 初始化個數 列印楊輝三角的前十行 triange 1...