python编程语言模块_用C/C++写Python的扩展模块

[C++] 纯文本查看 复制代码/*

*author: loxingxiaobing|小冰哟

*/

#include

#include

/* 我这里使用的是python3.7.1版本的库 */

#pragma comment(lib, "Python37.lib")

using namespace std;

/*

*遍历列表

*/

static PyObject* WalkingSequence_WalkingDownList(

PyObject* self,

PyObject* args

) {

//声明一个Python对象(列表)

PyObject* mylist;

//list是一个Python对象

if (!PyArg_ParseTuple(args, "O", &mylist))

return NULL;

//检查是否是一个列表

if (!PyList_Check(mylist))

return NULL;

//获取长度

Py_ssize_t list_len = PyList_Size(mylist);

cout << "列表长度: " << list_len << endl;

for (Py_ssize_t index=0; index < list_len; index++) {

//在Python中是mylist[isndex]中的形式获取元素,这里的做法一模一样

PyObject* item = PyList_GetItem(mylist, index);

//元素获取失败

if (!item) {

cerr << "#list:[Error~0]" << endl;

continue;

}

//这里直接调用Python对象的魔法方法__str__获取这个类型本该输出的样子

PyObject* py_str = PyObject_Str(item);

//函数调用成功返回非NULL的地址

if (py_str) {

//将字符串对象转换为C宽字符串

wchar_t* wc_str = PyUnicode_AsWideCharString(py_str, NULL);

if (wc_str) {

//输出宽字符串

wcout << L"list~[" << index << "]: " << wc_str << endl;

//记得释放

PyMem_Free(wc_str);

} else {

// 获取字符串出错!

cerr << "#List:[Error~2]" << endl;

}

//引用计数-1,表示本次获取到的字符串对象已经不用了

Py_XDECREF(py_str);

} else {

// 执行对象__str__方法失败

cerr << "#List:[Error~1]" << endl;

}

}

//返回列表长度

return Py_BuildValue("i", list_len);

}

/*

*遍历元组

*/

//这里的做法跟元组的几乎无差别(直接是拷贝过来稍稍修改)

static PyObject* WalkingSequence_WalkingDownTuple(

PyObject* self,

PyObject* args

) {

//声明一个Python对象(元组)

PyObject* mytuple;

//tuple是一个Python对象

if (!PyArg_ParseTuple(args, "O", &mytuple))

return NULL;

//检查是否是一个元组

if (!PyTuple_Check(mytuple))

return NULL;

//获取长度

Py_ssize_t tuple_len = PyTuple_Size(mytuple);

cout << "元表长度: " << tuple_len << endl;

for (Py_ssize_t index=0; index < tuple_len; index++) {

//在Python中是mytuple[index]中的形式获取元素,这里的做法一模一样

PyObject* item = PyTuple_GetItem(mytuple, index);

//元素获取失败

if (!item) {

cerr << "#tuple:[Error~0]" << endl;

continue;

}

//这里直接调用Python对象的魔法方法__str__获取这个类型本该输出的样子

PyObject* py_str = PyObject_Str(item);

//函数调用成功返回非NULL的地址

if (py_str) {

//将字符串对象转换为C宽字符串

wchar_t* wc_str = PyUnicode_AsWideCharString(py_str, NULL);

if (wc_str) {

//输出宽字符串

wcout << L"tuple~[" << index << "]: " << wc_str << endl;

//记得释放

PyMem_Free(wc_str);

} else {

// 获取字符串出错!

cerr << "#tuple:[Error~2]" << endl;

}

//引用计数-1,表示本次获取到的字符串对象已经不用了

Py_XDECREF(py_str);

} else {

// 执行对象__str__方法失败

cerr << "#tuple:[Error~1]" << endl;

}

}

//返回元组长度

return Py_BuildValue("i", tuple_len);

}

/*

*遍历字典

*/

static PyObject* WalkingSequence_WalkingDownDict(

PyObject* self,

PyObject* args

) {

//声明一个Python对象(字典)

PyObject* mydict;

//dict是一个Python对象

if (!PyArg_ParseTuple(args, "O", &mydict))

return NULL;

//检查是否是一个字典

if (!PyDict_Check(mydict))

return NULL;

/* 字典是有限集,可以获取长度 */

Py_ssize_t dict_len = PyDict_Size(mydict);

cout << "字典内元素个数: " << dict_len << endl;

PyObject* key;

PyObject* value;

/* 开始前pos必须初始化为0 */

Py_ssize_t pos = 0;

//遍历完返回0

while (PyDict_Next(mydict, &pos, &key, &value)) {

//管他啥类型,直接调用其__str__魔法方法,返回它本来该输出的样子

//这里得注意的是,字典的键不一定是字符串

PyObject* py_str_key = PyObject_Str(key);

if (py_str_key) {

wchar_t* wc_str_key = PyUnicode_AsWideCharString(py_str_key, NULL);

if (wc_str_key) {

//输出键

wcout << wc_str_key;

PyMem_Free(wc_str_key);

} else {

cerr << "#dict:[Error~2]" << endl;

Py_XDECREF(py_str_key);

continue;

}

Py_XDECREF(py_str_key);

} else {

cerr << "#dict:[Error~1]" << endl;

continue;

}

//输出冒号

cout.put(':');

/* 下面的步骤和上面的一样 */

PyObject* py_str_value = PyObject_Str(value);

if (py_str_value) {

wchar_t* wc_str_value = PyUnicode_AsWideCharString(py_str_value, NULL);

if (wc_str_value) {

//输出值

wcout << wc_str_value << endl;;

PyMem_Free(wc_str_value);

} else {

cerr << "#dict:[Error~4]" << endl;

}

Py_XDECREF(py_str_value);

} else {

cerr << "#dict:[Error~3]" << endl;

continue;

}

}

//Long类型对应的是Python中的整数

return PyLong_FromSsize_t(dict_len);

}

/*

*遍历集合

*/

static PyObject* WalkingSequence_WalkingDownSet(

PyObject* self,

PyObject* args

) {

//声明一个Python对象(集合)

PyObject* myset;

//dict是一个Python对象

if (!PyArg_ParseTuple(args, "O", &myset))

return NULL;

//检查是否是一个字典

if (!PySet_Check(myset))

return NULL;

//集合性质三要素之一:有限性

Py_ssize_t set_len = PySet_Size(myset);

/*

//集合肯定是可迭代的啦....

if (PyIter_Check(myset))

return NULL;

*/

//跟在python中用iter函数获取到一个迭代对象一样

PyObject* myiterator = PyObject_GetIter(myset);

PyObject* item;

//开始迭代,就类似于python中的myiterator = iter(myset);for item in myinterator: print(item)

while ((item = PyIter_Next(myiterator)) != NULL) {

PyObject* py_str = PyObject_Str(item);

if (py_str) {

wchar_t* wc_str = PyUnicode_AsWideCharString(py_str, NULL);

if (wc_str) {

wcout << wc_str << endl;

PyMem_Free(wc_str);

} else {

cerr << "#set:[myiterator~2]" << endl;

}

Py_XDECREF(py_str);

} else {

cerr << "#set:[myiterator~1]" << endl;

}

//注意这里!

Py_XDECREF(item);

}

return PyLong_FromSsize_t(set_len);

}

//我这里直接用宏来解决啦,函数名太长,如果此函数没有文档默认为NULL

#define WALKINGDOWNSEQUENCE_METHOD(name) {#name, WalkingSequence_##name, METH_VARARGS, NULL}

//格式{函数名字符串, 函数指针, 参数形式, 此函数/方法的文档(通过help函数获取)字符串}

//例如:{"WalkingDownList", WalkingSequence_WalkingDownList, METH_VARARGS, "这里是函数文档哟"}

/* 定义Python函数与C函数的映射表 */

static PyMethodDef WalkingSequenceMethods[] = {

/* 下面的第一条与 {"WalkingDownList", WalkingSequence_WalkingDownList, METH_VARARGS, NULL} 等效 */

WALKINGDOWNSEQUENCE_METHOD(WalkingDownList),

WALKINGDOWNSEQUENCE_METHOD(WalkingDownTuple),

WALKINGDOWNSEQUENCE_METHOD(WalkingDownDict),

WALKINGDOWNSEQUENCE_METHOD(WalkingDownSet),

{NULL, NULL, 0, NULL} //用全空的结构体成员元素作为结尾,也可以直接写{NULL},简洁

};

//文档就是可以通过help函数获取的字符串

/* 定义模块描述表(Python3.x必须定义) */

static PyModuleDef WalkingSequenceModule = {

PyModuleDef_HEAD_INIT, //这个是必须加的

"WalkingSequence", //模块的名字

"Here\'s WalkingSequenceModule's document", //模块文档

-1, //给-1默认,代表模块存在于全局表

WalkingSequenceMethods, //模块的函数映射表

NULL, NULL, NULL, NULL // 目前还不用对模块进行特殊处理,全部默认NULL

};

/* 这里非常关键,是导出C函数到Python的接口函数 */

/* 这里使用的是Python3.x的 c/api 函数导出接口格式,有别于Python2.x的 */

/* 接口函数格式 PyInit_+模块文件名 */

PyMODINIT_FUNC PyInit_WalkingSequence(void) {

/* 创建模块并返回模块 */

return PyModule_Create(&WalkingSequenceModule);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值