设为首页 加入收藏

TOP

C语言解析Python字典的代码实例(一)
2018-04-04 08:53:16 】 浏览:644
Tags:语言 解析 Python 字典 代码 实例

这里我们简单说一些背景,就是突然想写一点用C去写Python库的东西,下面的这些方法和用法大部分参考官方介绍

Python中字典

从参数中获取

从参数中获取的情况一般有两种,一般是我们如果明确了传入类型就是字典,并且需要知道需要解析的key,那么可以采用如下的方式进行解析:

static PyObject *my_func(PyObject* self, PyObject* args, PyObject* keyds)
{
    static char* kwlist[] = {"age","name","level",NULL};
    int age;
    char *name;
    int level;
    if(!PyArg_ParseTupleAndKeywords(args,keyds,"isi", kwlist, &age,&name,&level))
    {
        return NULL;
    }
    /* 其他的工作 */
}

其中kwlist是需要获取的字典中的key列表,但是这样的话,我们的参数就变成了三个,因此需要修改一下声明:

{
    "my_func",
    (PyCFunction)my_func,
    METH_VARARGS | METH_KEYWORDS,
    "my_func"
},

在函数绑定的时候进行了一次类型转换。

还有一种情况是,我们只是获取字典,用于后面的解析工作,也不确定字典中的keylist,那么可以使用如下的方式来读:

PyObject *dict;
if(!PyArg_ParseTuple(args, "O!", &PyDict_Type,&dict))
//if(!PyArg_ParseTuple(args, "O", &dict))
{
    return NULL;
}

两种方式均可以获取字典,其中O和O!的区别,后续再说。

解析一个dict

获取dict中的key

我们知道Python中的dict的keys其实是一个list,同样,在C语言中也是一样的,我们通过下面这个函数获取keys_list:

PyAPI_FUNC(PyObject *) PyDict_Keys(PyObject *mp);

该函数的返回值的同样也是一个PyObject*的类型,也就是我们常说的key_list。如果想便利keys_list中的key,这可以使用list的函数进行遍历,函数原型如下:

PyAPI_FUNC(PyObject *) PyList_GetItem(PyObject *, Py_ssize_t);

其中两个参数分别是list以及在list中的位置。简单一点的遍历的例子如下:

PyObject* py_keys = PyDict_Keys(dict);
for(int i =0;i< PyList_Size(py_keys);++i)
{
    //do something
    //...
}

通过key获取字典中的值

接下来就是通过key获取字典中的值,通常会借用下面的函数

PyAPI_FUNC(PyObject *) PyDict_GetItem(PyObject *mp, PyObject *key);
PyAPI_FUNC(PyObject *) PyDict_GetItemString(PyObject *dp, const char *key);

通过函数原型很容易知道,第一个API是通过PyObject获取,第二个是通过字符串key获取。

因为C语言不同于Python的中一切皆为对象,这里需要判断一下val的类型,以及完成对应类型的转换:

字符串类型

Python2中是采用PyString_Check函数进行甄别的,判断是否为字符串,通过PyString_AsString函数完成从PyObject* 到char*的转换。

在Python3中是使用PyUnicode_Check进行是否为字符串的判断,通过PyUnicode_AsUTF8可以完成从PyObject* 到char*的转换。

整型

在Python2中,有两个文件均提供了判断的函数:

1. intobject.h提供了PyInt_Check(op)

2. longobject.h提供了PyLong_Check(op)

那么肯定是两种转换的接口:

1. intobject.h提供了PyAPI_FUNC(int) _PyInt_AsInt(PyObject *)

2. intobject.h提供了PyAPI_FUNC(long) PyInt_AsLong(PyObject *)

3. longobject.h提供了PyAPI_FUNC(long) PyLong_AsLong(PyObject *);

4. longobject.h提供了 PyAPI_FUNC(PY_LONG_LONG) PyLong_AsLongLong(PyObject *)

简单的例子如下:

int val = PyInt_AsLong(py_val);

在Python3中则没有这么多的转换函数,已经没有PyInt这一些函数了,因此只有Python2中一半的函数:

PyLong_Check(op) 
longobject.h:PyAPI_FUNC(long) PyLong_AsLong(PyObject *);
longobject.h:PyAPI_FUNC(unsigned long) PyLong_AsUnsignedLong(PyObject *)

字典类型

同样的,在Python只能够字典的value也可以是字典,因此可以通过PyDict_Check来判断这个值得类型是不是字典。从而进行更深入的解析。

下面是一个简单的把dict读入到一个buffer中例子,其实也可以构建一个cpp中的类似Python的字典的类型。

static int dict2str(PyObject* dict , char* buffer, int buf_size)
{
    int n_pos = 0;
    int buf_cost_len = 0;
    int buf_unused_len = buf_size;
    if(dict == NULL)
    {
        //printf("the dict is null\n");
        return -1;
    }
    if(NULL == buffer || buf_size <=0)
    {
        //printf("the buffer is null\n");
        return -1;
    }
    PyObject* py_keys = PyDict_Keys(dict);
    /* debug */
    #define DEBUG_UINT(val) \
    do{     \
        printf("[%s][%s][%d][%s][%u]\n",__FILE__,__FUNCTION__,__LINE__,#val,val); \
    }while(0)
    DEBUG_UINT(PyDict_Size(dict));
    DEBUG_
编程开发网
首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇C语言重定位代码分析 下一篇c语言心形告白代码实现

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

array(4) { ["type"]=> int(8) ["message"]=> string(24) "Undefined variable: jobs" ["file"]=> string(32) "/mnt/wp/cppentry/do/bencandy.php" ["line"]=> int(214) }