使用c语言扩展python第二篇,接收不同类型的参数
xuxiaobo.c
#include <Python.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int count_substrings(const char *str, const char *delim) {
int count = 0;
char *token = strtok((char *)str, delim); // 注意这里的强制类型转换
while (token != NULL) {
count++;
token = strtok(NULL, delim); // 继续分割剩余的字符串
}
return count;
}
//定义打招呼函数
static PyObject* xuxiaobo_hello(PyObject* self, PyObject* args) {
char *name;
char *dest = malloc(1024);
if (!PyArg_ParseTuple(args, "s", &name)) {
return NULL;
}
/*
strcpy(dest, "");
strcat(dest, "hello, ");
strcat(dest, name);
strcat(dest, "!");
*/
sprintf(dest, "你好, %s!", name);
return Py_BuildValue("s", dest);
}
//定义计算平方函数
static PyObject* xuxiaobo_square(PyObject* self, PyObject* args) {
int num;
if (!PyArg_ParseTuple(args, "i", &num)) {
return NULL;
}
return Py_BuildValue("i", num * num);
}
//定义计算立方函数
static PyObject* xuxiaobo_cube(PyObject* self, PyObject* args) {
double num;
if (!PyArg_ParseTuple(args, "d:xuxiaobo_cube", &num)) {
return NULL;
}
return Py_BuildValue("d", num * num * num);
}
//定义解析url参数函数
static PyObject* xuxiaobo_parse_url(PyObject* self, PyObject* args) {
char *params_str;
char *delim = "=&,. ";
PyObject* pDict = PyDict_New();
if (!PyArg_ParseTuple(args, "s", ¶ms_str)) {
return NULL;
}
int i = 0;
char *token = strtok(params_str, delim);
while (token != NULL) {
char key[1024];
char value[1024];
if(i%2 == 0){
strcpy(key, token);
//printf("debug key=>%s\n", key);
} else{
strcpy(value, token);
//printf("debug value=>%s\n", value);
PyDict_SetItemString(pDict, key, Py_BuildValue("s", value));
}
token = strtok(NULL, delim);
i++;
}
//printf("i=>%d\n", i);
return pDict;
}
//定义字符串切分函数,返回list
static PyObject* xuxiaobo_split_str_list(PyObject* self, PyObject* args) {
char *params_str;
char *delim = "&,. ";
PyObject* plist = PyList_New(0);
if (!PyArg_ParseTuple(args, "s", ¶ms_str)) {
return NULL;
}
char *token = strtok(params_str, delim);
while (token != NULL) {
PyList_Append(plist, Py_BuildValue("s", token));
token = strtok(NULL, delim);
}
return plist;
}
//定义字符串切分函数,返回tuple
static PyObject* xuxiaobo_split_str_tuple(PyObject* self, PyObject* args) {
char *delim = "&,. ";
char *params_str;
char params_str_tmp[1024];
if (!PyArg_ParseTuple(args, "s", ¶ms_str)) {
return NULL;
}
strcpy(params_str_tmp, params_str);
int max = count_substrings(params_str_tmp, delim);
PyObject* ptuple = PyTuple_New(max);
int i = 0;
char *token = strtok(params_str, delim);
while (token != NULL && i < max) {
//printf("[%d]debug=>%s\n", i, token);
PyTuple_SetItem(ptuple, i, Py_BuildValue("s", token));
token = strtok(NULL, delim);
i++;
}
return ptuple;
}
//定义字符串切分函数,返回set
static PyObject* xuxiaobo_split_str_set(PyObject* self, PyObject* args) {
char *delim = "&,. ";
char *params_str;
PyObject* pset = PySet_New(NULL);
if (!PyArg_ParseTuple(args, "s", ¶ms_str)) {
return NULL;
}
int i = 0;
char *token = strtok(params_str, delim);
while (token != NULL) {
//printf("[%d]debug=>%s\n", i, token);
if(PySet_Add(pset, Py_BuildValue("s", token)) == -1){
Py_DECREF(pset);
return NULL;
}
token = strtok(NULL, delim);
i++;
}
return pset;
}
//定义季节检测函数,返回bool
static PyObject* xuxiaobo_is_season(PyObject* self, PyObject* args) {
char *params_str;
char params_str_tmp[1024];
if (!PyArg_ParseTuple(args, "s", ¶ms_str)) {
return NULL;
}
strcpy(params_str_tmp, params_str);
if(strcmp(params_str_tmp, "春") == 0 ||
strcmp(params_str_tmp, "夏") == 0 ||
strcmp(params_str_tmp, "秋") == 0 ||
strcmp(params_str_tmp, "冬") == 0){
return PyBool_FromLong(1);
}
return PyBool_FromLong(0);
}
//定义多个季节检测函数,返回bool组成的列表
static PyObject* xuxiaobo_is_season_multi_list(PyObject* self, PyObject* args) {
PyObject* list;
Py_ssize_t len;
int i;
char params_str_tmp[1024];
PyObject* plist = PyList_New(0);
const char *item_str;
if (!PyArg_ParseTuple(args, "O", &list)) {
return NULL;
}
len = PyList_Size(list);
//printf("len=>%lld\n", len);
for (i = 0; i < len; i++) {
PyObject* item = PyList_GetItem(list, i);
item_str = PyUnicode_AsUTF8(item);
//printf("item_str=>%s\n", item_str);
strcpy(params_str_tmp, item_str);
if(strcmp(params_str_tmp, "春") == 0 ||
strcmp(params_str_tmp, "夏") == 0 ||
strcmp(params_str_tmp, "秋") == 0 ||
strcmp(params_str_tmp, "冬") == 0){
PyList_Append(plist, PyBool_FromLong(1));
} else{
PyList_Append(plist, PyBool_FromLong(0));
}
}
return plist;
}
//定义多个季节检测函数,返回bool组成的tuple
static PyObject* xuxiaobo_is_season_multi_tuple(PyObject* self, PyObject* args) {
PyObject* iptuple;
Py_ssize_t len;
int i;
char params_str_tmp[1024];
const char *item_str;
if (!PyArg_ParseTuple(args, "O", &iptuple)) {
return NULL;
}
len = PyTuple_Size(iptuple);
PyObject* ptuple = PyTuple_New(len);
//printf("len=>%lld\n", len);
for (i = 0; i < len; i++) {
PyObject* item = PyTuple_GetItem(iptuple, i);
item_str = PyUnicode_AsUTF8(item);
//printf("item_str=>%s\n", item_str);
strcpy(params_str_tmp, item_str);
if(strcmp(params_str_tmp, "春") == 0 ||
strcmp(params_str_tmp, "夏") == 0 ||
strcmp(params_str_tmp, "秋") == 0 ||
strcmp(params_str_tmp, "冬") == 0){
PyTuple_SetItem(ptuple, i, PyBool_FromLong(1));
} else{
PyTuple_SetItem(ptuple, i, PyBool_FromLong(0));
}
}
return ptuple;
}
//定义多个季节检测函数,返回key=>val.bool组成的dict
static PyObject* xuxiaobo_is_season_multi_dict(PyObject* self, PyObject* args) {
PyObject* list;
Py_ssize_t len;
int i;
char params_str_tmp[1024];
const char *item_str;
PyObject* pDict = PyDict_New();
if (!PyArg_ParseTuple(args, "O", &list)) {
return NULL;
}
len = PyList_Size(list);
//printf("len=>%lld\n", len);
for (i = 0; i < len; i++) {
PyObject* item = PyList_GetItem(list, i);
item_str = PyUnicode_AsUTF8(item);
//printf("item_str=>%s\n", item_str);
strcpy(params_str_tmp, item_str);
if(strcmp(params_str_tmp, "春") == 0 ||
strcmp(params_str_tmp, "夏") == 0 ||
strcmp(params_str_tmp, "秋") == 0 ||
strcmp(params_str_tmp, "冬") == 0){
PyDict_SetItemString(pDict, item_str, PyBool_FromLong(1));
} else{
PyDict_SetItemString(pDict, item_str, PyBool_FromLong(0));
}
}
return pDict;
}
// 实现函数,接收字典参数并返回其内容打印字符串
static PyObject* xuxiaobo_print_dict(PyObject* self, PyObject* args, PyObject* kwargs) {
PyObject *pdict;
if (!PyArg_ParseTuple(args, "O:xuxiaobo_print_dict", &pdict)) {
return NULL;
}
if (!PyDict_Check(pdict)) {
PyErr_SetString(PyExc_TypeError, "xuxiaobo_print_dict() requires a dictionary");
return NULL;
}
// 打印字典内容
PyObject *key, *value;
Py_ssize_t pos = 0;
char result[8192] = {""};
while (PyDict_Next(pdict, &pos, &key, &value)) {
const char *tmpkey1 = PyUnicode_AsUTF8(key);
const char *tmpvalue1 = PyUnicode_AsUTF8(value);
char tmpkey2[1024];
char tmpvalue2[1024];
strcpy(tmpkey2, tmpkey1);
strcpy(tmpvalue2, tmpvalue1);
char *tmpstr = malloc(1024);
sprintf(tmpstr, "%s => %s ", tmpkey2, tmpvalue2);
//printf("%s\n", tmpstr);
strcat(result, tmpstr);
//printf("%s\n", result);
}
return Py_BuildValue("s", result);
}
static PyObject* xuxiaobo_set_to_list(PyObject *self, PyObject *args) {
PyObject *py_set;
if (!PyArg_ParseTuple(args, "O", &py_set)) {
return NULL;
}
if (!PySet_Check(py_set)) {
PyErr_SetString(PyExc_TypeError, "Expected a set");
return NULL;
}
// 将set转换为list,便于在C中处理
PyObject *py_list = PySequence_List(py_set);
if (py_list == NULL) {
return NULL;
}
// 返回list对象
return py_list;
}
static PyObject* xuxiaobo_get_bool_param(PyObject* self, PyObject* arg) {
if (!PyBool_Check(arg)) {
PyErr_SetString(PyExc_TypeError, "Argument must be a boolean");
return NULL;
}
int value = PyObject_IsTrue(arg);
if (value == -1) {
return NULL;
}
char result[8192] = {""};
char *tmpstr = malloc(1024);
sprintf(tmpstr, "收到布尔类型参数: %s", value ? "True" : "False");
strcat(result, tmpstr);
return Py_BuildValue("s", result);
}
static PyObject* xuxiaobo_get_multi_param(PyObject* self, PyObject* args, PyObject* kwargs) {
static char* kwlist[] = {"name", "age", "weight", "kemus", NULL};
const char* name;
int age;
double weight;
PyObject *kemus;
// 解析位置参数和关键字参数
//PyArg_ParseTupleAndKeywords可以同时处理位置参数和关键字参数
//s|id"表示第一个参数是必须的字符串,后面的两个参数是可选的,其中i代表整数,d代表浮点数。|表示后面的参数是可选的
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sidO", kwlist, &name, &age, &weight, &kemus)) {
return NULL;
}
if (!PySet_Check(kemus)) {
PyErr_SetString(PyExc_TypeError, "kemus argument must be a set");
return NULL;
}
PyObject *iter = PyObject_GetIter(kemus);
PyObject *item;
char kemustr[8192] = {""};
while ((item = PyIter_Next(iter)) != NULL) {
const char *tmpvalue = PyUnicode_AsUTF8(item);
strcat(kemustr, tmpvalue);
strcat(kemustr, ",");
}
// 使用参数
char result[8192] = {""};
char *tmpstr = malloc(1024);
sprintf(tmpstr, "姓名: %s, 年龄: %d, 体重: %f, 考试科目: %s", name, age, weight, kemustr);
strcat(result, tmpstr);
return Py_BuildValue("s", result);
}
static PyMethodDef XuxiaoboMethods[] = {
{"hello", xuxiaobo_hello, METH_VARARGS, NULL},
{"square", xuxiaobo_square, METH_VARARGS, NULL},
{"cube", xuxiaobo_cube, METH_VARARGS, NULL},
{"parse_url", xuxiaobo_parse_url, METH_VARARGS, NULL},
{"split_str_list", xuxiaobo_split_str_list, METH_VARARGS, NULL},
{"split_str_tuple", xuxiaobo_split_str_tuple, METH_VARARGS, NULL},
{"split_str_set", xuxiaobo_split_str_set, METH_VARARGS, NULL},
{"is_season", xuxiaobo_is_season, METH_VARARGS, NULL},
{"is_season_multi_list", xuxiaobo_is_season_multi_list, METH_VARARGS, NULL},
{"is_season_multi_tuple", xuxiaobo_is_season_multi_tuple, METH_VARARGS, NULL},
{"is_season_multi_dict", xuxiaobo_is_season_multi_dict, METH_VARARGS, NULL},
{"print_dict", xuxiaobo_print_dict, METH_VARARGS | METH_KEYWORDS, NULL},
{"set_to_list", xuxiaobo_set_to_list, METH_VARARGS, NULL},
{"get_bool_param", xuxiaobo_get_bool_param, METH_O, NULL},
{"get_multi_param", xuxiaobo_get_multi_param, METH_VARARGS | METH_KEYWORDS, NULL},
{NULL, NULL, 0, NULL}
};
static struct PyModuleDef xuxiaobomodule = {
PyModuleDef_HEAD_INIT,
"xuxiaobo",
NULL,
-1,
XuxiaoboMethods
};
PyMODINIT_FUNC PyInit_xuxiaobo(void) {
return PyModule_Create(&xuxiaobomodule);
}
test.py
#coding=utf-8
from xuxiaobo import *
import json
input = "徐小波"
output = hello(input)
print("函数调用: %s hello('%s')" % (type(input), input))
print("输出:%s %s" % (type(output), output))
print()
input = 3
output = square(input)
print("函数调用: %s square(%s)" % (type(input), input))
print("输出:%s %s" % (type(output), output))
print()
input = 3.0
output = cube(input)
print("函数调用: %s cube(%s)" % (type(input), input))
print("输出:%s %s" % (type(output), output))
print()
input = "a=1&b=2&c=3&d=我爱北京天安门"
output = parse_url(input)
print("函数调用: %s parse_url('%s')" % (type(input), input))
print("输出:%s %s" % (type(output), json.dumps(output, ensure_ascii=False)))
print()
input = "河.北.大.学.徐,小&波"
output = split_str_list(input)
print("函数调用: %s split_str_list('%s')" % (type(input), input))
print("输出:%s %s" % (type(output), json.dumps(output, ensure_ascii=False)))
print()
input = "河.北.大.学.徐,小.波& 啊"
output = split_str_tuple(input)
print("函数调用: %s split_str_tuple('%s')" % (type(input), input))
print("输出:%s %s" % (type(output), json.dumps(output, ensure_ascii=False)))
print()
input = "河.北.大 学.河.北.大 学 河.北 大&学"
output = split_str_set(input)
print("函数调用: %s split_str_set('%s')" % (type(input), input))
print("输出:%s %s" % (type(output), output))
print()
input = "夏"
output = is_season(input)
print("函数调用: %s is_season('%s')" % (type(input), input))
print("输出:%s %s" % (type(output), output))
print()
input = ["春", "夏", "秋", "东", "冬"]
output = is_season_multi_list(input)
print("函数调用: %s is_season_multi_list(%s)" % (type(input), json.dumps(input, ensure_ascii=False)))
print("输出:%s %s" % (type(output), json.dumps(output, ensure_ascii=False)))
print()
input = ("春", "下", "秋", "冬", "上")
output = is_season_multi_tuple(input)
print("函数调用: %s is_season_multi_tuple(%s)" % (type(input), json.dumps(input, ensure_ascii=False)))
print("输出:%s %s" % (type(output), json.dumps(output, ensure_ascii=False)))
print()
input = ["春", "下", "秋", "冬", "上"]
output = is_season_multi_dict(input)
print("函数调用: %s is_season_multi_dict(%s)" % (type(input), json.dumps(input, ensure_ascii=False)))
print("输出:%s %s" % (type(output), json.dumps(output, ensure_ascii=False)))
print()
input = {'下': '下邳', '秋': '秋天', '冬': '司机入伙', '上': '13110813222', '春三': '2222'}
output = print_dict(input)
print("函数调用: %s print_dict(%s)" % (type(input), json.dumps(input, ensure_ascii=False)))
print("输出:%s %s" % (type(output), json.dumps(output, ensure_ascii=False)))
print()
input = {'下', '秋', '冬', '上'}
output = set_to_list(input)
print("函数调用: %s set_to_list(%s)" % (type(input), input))
print("输出:%s %s" % (type(output), json.dumps(output, ensure_ascii=False)))
print()
input = False
output = get_bool_param(input)
print("函数调用: %s get_bool_param(%s)" % (type(input), input))
print("输出:%s %s" % (type(output), output))
print()
input = ('徐香香', 15, 103.5, {'语文', '数学', '英语'})
output = get_multi_param(*input)
print("函数调用: %s get_multi_param(%s)" % (type(input), input))
print("输出:%s %s" % (type(output), output))
print()
测试输出:
函数调用: <class 'str'> hello('徐小波')
输出:<class 'str'> 你好, 徐小波!
函数调用: <class 'int'> square(3)
输出:<class 'int'> 9
函数调用: <class 'float'> cube(3.0)
输出:<class 'float'> 27.0
函数调用: <class 'str'> parse_url('a=1&b=2&c=3&d=我爱北京天安门')
输出:<class 'dict'> {"a": "1", "b": "2", "c": "3", "d": "我爱北京天安门"}
函数调用: <class 'str'> split_str_list('河.北.大.学.徐,小&波')
输出:<class 'list'> ["河", "北", "大", "学", "徐", "小", "波"]
函数调用: <class 'str'> split_str_tuple('河.北.大.学.徐,小.波& 啊')
输出:<class 'tuple'> ["河", "北", "大", "学", "徐", "小", "波", "啊"]
函数调用: <class 'str'> split_str_set('河.北.大 学.河.北.大 学 河.北 大&学')
输出:<class 'set'> {'河', '学', '大', '北'}
函数调用: <class 'str'> is_season('夏')
输出:<class 'bool'> True
函数调用: <class 'list'> is_season_multi_list(["春", "夏", "秋", "东", "冬"])
输出:<class 'list'> [true, true, true, false, true]
函数调用: <class 'tuple'> is_season_multi_tuple(["春", "下", "秋", "冬", "上"])
输出:<class 'tuple'> [true, false, true, true, false]
函数调用: <class 'list'> is_season_multi_dict(["春", "下", "秋", "冬", "上"])
输出:<class 'dict'> {"春": true, "下": false, "秋": true, "冬": true, "上": false}
函数调用: <class 'dict'> print_dict({"下": "下邳", "秋": "秋天", "冬": "司机入伙", "上": "13110813222", "春三": "2222"})
输出:<class 'str'> "下 => 下邳 秋 => 秋天 冬 => 司机入伙 上 => 13110813222 春三 => 2222 "
函数调用: <class 'set'> set_to_list({'秋', '下', '冬', '上'})
输出:<class 'list'> ["秋", "下", "冬", "上"]
函数调用: <class 'bool'> get_bool_param(False)
输出:<class 'str'> 收到布尔类型参数: False
函数调用: <class 'tuple'> get_multi_param(('徐香香', 15, 103.5, {'英语', '语文', '数学'}))
输出:<class 'str'> 姓名: 徐香香, 年龄: 15, 体重: 103.500000, 考试科目: 英语,语文,数学,
本文来自博客园,作者:河北大学-徐小波,转载请注明原文链接:https://www.cnblogs.com/xuxiaobo/p/18978808

浙公网安备 33010602011771号