Python C API 使用詳解(二)

來源:互聯網
上載者:User

標籤:mono   dict   account   code   虛擬   mon   efault   data   資料   

簡介

介紹Python C API中的列表、元組、字典的使用,詳細的進行了API中方法的介紹。

Python List API

List API 簡單介紹

int PyList_Check(PyObject *p) 判斷是否是一個Python List(列表)

PyObject* PyList_New(Py_ssize_t len) 建立一個列表

Py_ssize_t PyList_Size(PyObject *list) 擷取列表元素的個數 len(list)

Py_ssize_t PyList_GET_SIZE(PyObject *list) 和PyList_Size 一樣,但是就是沒有錯誤檢查

PyObject PyList_GetItem(PyObject list, Py_ssize_t index) 從列表裡面擷取一個元素,計數器不會加1

PyObject PyList_GET_ITEM(PyObject list, Py_ssize_t i) 和PyList_GetItem一樣,但是就是沒有錯誤檢查

int PyList_SetItem(PyObject list, Py_ssize_t index, PyObject item) 設定別表指定位置的值,下標的所在的位置必須是有值的,並且是有效

void PyList_SET_ITEM(PyObject list, Py_ssize_t i, PyObject o) 和PyList_SetItem一樣,但是就是沒有錯誤檢查

int PyList_Insert(PyObject list, Py_ssize_t index, PyObject item) 在列表指定位置插入值 list.insert(index, item)

int PyList_Append(PyObject list, PyObject item) 在列表尾部追加值 list.append(item)

PyObject PyList_GetSlice(PyObject list, Py_ssize_t low, Py_ssize_t high) 擷取列表裡面一段切片資料,一段指定範圍的資料 list[low:higt]

int PyList_SetSlice(PyObject list, Py_ssize_t low, Py_ssize_t high, PyObject itemlist) 設定列表分區資料,指定列表範圍的資料 list[low:higt] = itemlist

int PyList_Sort(PyObject *list) 對列表資料進行排序 list.sort()

int PyList_Reverse(PyObject *list) 把列表裡面的所有資料反轉 list.reverse()

PyObject PyList_AsTuple(PyObject list) 將Python列錶轉為Python元組 tuple(list)

執行個體

注意事項: 不限制大小的Python列表對象,應該用Append初始化資料

設定大小的Python列表對象,應該用SetItem初始化資料, 如果用Append的話,會出現" 段錯誤 (核心已轉儲) "的情況

標頭檔

//// Created by lanyulei on 18-9-3.//#ifndef PRINT_DEMO1_PYLIST_H#define PRINT_DEMO1_PYLIST_H#include <Python.h>#include "print.h"// 建立一個固定大小的列表void ListNumber();// 建立一個可以無限擴充的列表void ListExpansion();#endif //PRINT_DEMO1_PYLIST_H

源檔案

//// Created by lanyulei on 18-9-3.//#include <stdio.h>#include <stdlib.h>#include <string.h>#include "pyList.h"// 有長短限制的列表void ListNumber() {    PyObject* pyList = PyList_New(3);    // 建立一個大小為3的列表    PyObject* pyId = Py_BuildValue("i", 123);   // 建立Python 整型對象    PyList_SetItem(pyList, 0, pyId);   // 將Python整型對象插入到Python列表對象中    PyObject* pyName = Py_BuildValue("s", "lanyulei");   // 建立一個字串python對象    PyList_SetItem(pyList, 1, pyName);   // 插入到Python列表對象裡面去    PyObject* pyFloat = Py_BuildValue("f", 23.98f);   // 建立一個浮點類型的Python對象    PyList_SetItem(pyList, 2, pyFloat);   // 將其插入到Python列表對象中    int listLength = PyList_Size(pyList);   // 擷取列表的長度    printf("列表長度: %d\n", listLength);    print_pyobject(pyList);    // 列印列表資料    PyObject* pyName2 = Py_BuildValue("s", "LanYuLei");  // 建立一個字串python對象    PyList_Insert(pyList, 1, pyName2);   // 在下標為1的位置插入一條資料    print_pyobject(pyList);    // 列印列表資料    printf("------------sort-------------\n");    PyList_Sort(pyList);    // 對列表進行排序    print_pyobject(pyList);    // 列印列表資料    printf("---------------reverse--------------\n");    PyList_Reverse(pyList);    // 反轉列表資料    print_pyobject(pyList);    // 列印列表資料    printf("----------------slice----------------\n");    PyObject* pySlice = PyList_GetSlice(pyList, 1, 3);   // 擷取分區資料    print_pyobject(pySlice);    // 列印分區資料}// 沒有大小限制的列表void ListExpansion(){    PyObject* pyList = PyList_New(0);    // 建立一個沒有大小限制的列表,所以參數為 0    PyObject* pyId = Py_BuildValue("i", 123);   // 建立Python 整型對象    PyList_Append(pyList, pyId);   // 將Python整型對象追加到Python列表對象中    PyObject* pyName = Py_BuildValue("s", "lanyulei");   // 建立一個字串python對象    PyList_Append(pyList, pyName);   // 追加到Python列表對象裡面去    PyObject* pyFloat = Py_BuildValue("f", 23.98f);   // 建立一個浮點類型的Python對象    PyList_Append(pyList, pyFloat);   // 將其追加到Python列表對象中    print_pyobject(pyList);    PyObject* py_data = PyList_GetItem(pyList, 0);   // 擷取下標為0的資料    print_pyobject(py_data);}
Python Tuple API

Tuple API 簡單介紹

int PyTuple_Check(PyObject *p) 判斷是否是一個元組對象

PyObject* PyTuple_New(Py_ssize_t len) 建立一個Python元組對象,注意元組建立是必須設定長度的,如果設定長度為0,則這個元組對象是一個空的元組

Py_ssize_t PyTuple_Size(PyObject *p) 擷取元組的長度,即元組的大小

Py_ssize_t PyTuple_GET_SIZE(PyObject *p) 和PyTuple_Size一樣,只不過這個方法沒有錯誤檢查的機制

PyObject PyTuple_GetItem(PyObject p, Py_ssize_t pos) 擷取元組內指定下標的值

PyObject PyTuple_GET_ITEM(PyObject p, Py_ssize_t pos) 和PyTuple_GetItem一樣,只不過這個方法沒有錯誤檢查的機制

PyObject PyTuple_GetSlice(PyObject p, Py_ssize_t low, Py_ssize_t high) 擷取分區資料 p[lwo, higt]

int PyTuple_SetItem(PyObject p, Py_ssize_t pos, PyObject o) 設定元組指定下標的值

void PyTuple_SET_ITEM(PyObject p, Py_ssize_t pos, PyObject o) 和PyTuple_SetItem一樣,只不過這個方法沒有錯誤檢查的機制

int _PyTuple_Resize(PyObject **p, Py_ssize_t newsize) 改變元組的大小

執行個體

標頭檔

//// Created by lanyulei on 18-9-4.//#ifndef PRINT_DEMO1_PYTUPLE_H#define PRINT_DEMO1_PYTUPLE_H#include <Python.h>#include <string.h>#include <stdio.h>#include <stdlib.h>#include "print.h"// 元組的使用void test_tuple();#endif //PRINT_DEMO1_PYTUPLE_H

源檔案

//// Created by lanyulei on 18-9-4.//#include "pyTuple.h"void test_tuple(){    PyObject* pyTuple = PyTuple_New(3);   // 建立一個元組    PyObject* pyId = Py_BuildValue("i", 1);   // 建立一個Python整型對象    PyTuple_SetItem(pyTuple, 0, pyId);   // 向指定的下標傳遞資料    PyObject* pyString = Py_BuildValue("s", "lanyulei");   // 建立一個Python字串對象    PyTuple_SetItem(pyTuple, 1, pyString);    PyObject* pyFloat = Py_BuildValue("f", 165.46f);    // 建立一個Python浮點對象    PyTuple_SetItem(pyTuple, 2, pyFloat);    int tupleLength = PyTuple_Size(pyTuple);    printf("pyTuple size: %d\n", tupleLength);    print_pyobject(pyTuple);    printf("----------------------PyTuple_GetItem--------------------------\n");    PyObject* pyData = PyTuple_GetItem(pyTuple, 0);   // 擷取元組指定下標的資料    print_pyobject(pyData);    printf("------------------------遍曆元組--------------------------\n");    // 遍曆元組資料    for (int i = 0; i < PyTuple_Size(pyTuple); i++){        PyObject* pyData = PyTuple_GetItem(pyTuple, i);        print_pyobject(pyData);    }    printf("------------------------擷取分區資料--------------------------\n");    PyObject* pySlice = PyTuple_GetSlice(pyTuple, 1, PyTuple_Size(pyTuple));   // 擷取切片資料    print_pyobject(pySlice);    printf("------------------------修改元組長度--------------------------\n");    printf("原始長度: %d\n", tupleLength);    _PyTuple_Resize(&pyTuple, 5);   // 修改元組長度,第一個參數是一個指標    printf("resize tuple length: %ld\n", PyTuple_Size(pyTuple));}
Python Dict API

Dict API 簡單介紹

int PyDict_Check(PyObject *p) 判斷對象是不是一個字典

PyObject* PyDict_New() 建立一個Python對象

void PyDict_Clear(PyObject *p) 清空Python對象的資料

int PyDict_Contains(PyObject p, PyObject key) 判斷字典內是否存在一個索引值資料

PyObject PyDict_Copy(PyObject p) 拷貝一個字典的資料,產生一個新的Python字典對象

int PyDict_SetItem(PyObject p, PyObject key, PyObject *val) 給Python字典對象設定新的索引值資料

int PyDict_SetItemString(PyObject p, const char key, PyObject *val) 和PyDict_SetItem類似,只不過鍵是C語言char資料類型的資料

int PyDict_DelItem(PyObject p, PyObject key) 刪除Python索引值資料

int PyDict_DelItemString(PyObject p, const char key) 和PyDict_DelItem類似,只不過鍵是C語言char資料類型的資料

PyObject PyDict_GetItem(PyObject p, PyObject *key) 擷取Python字典對象的鍵的值

PyObject PyDict_GetItemWithError(PyObject p, PyObject *key) 和PyDict_GetItem一樣,只不過返回內容相關的錯誤資訊

PyObject PyDict_GetItemString(PyObject p, const char *key) 和PyDict_GetItem一樣,只不過索引值C語言中char資料類型的資料

PyObject PyDict_SetDefault(PyObject p, PyObject key, PyObject default) 設定Python字典對象的預設值,當擷取的Key不存在的時候則返回當前的預設資料 dict.setdefault()

PyObject PyDict_Items(PyObject p) 返回一個Python字典對象所有資料的PyListObject, dict.items()

PyObject PyDict_Keys(PyObject p) 返回一個Python字典對象的所有的Key資料 dict.keys()

PyObject PyDict_Values(PyObject p) 返回一個Python字典對象的所有Value資料 dict.values()

Py_ssize_t PyDict_Size(PyObject *p) 擷取Python字典的大小 len(dict)

int PyDict_Next(PyObject p, Py_ssize_t ppos, PyObject pkey, PyObject pvalue) 遍曆擷取Python字典對象的所有資料, 下面是官方提供的例子

PyObject *key, *value;Py_ssize_t pos = 0;   // 初始值必須為0, 表示遍曆所有Python字典對象資料while (PyDict_Next(self->dict, &pos, &key, &value)) {    /* do something interesting with the values... */    ...}PyObject *key, *value;Py_ssize_t pos = 0;while (PyDict_Next(self->dict, &pos, &key, &value)) {    long i = PyLong_AsLong(value);    if (i == -1 && PyErr_Occurred()) {        return -1;    }    PyObject *o = PyLong_FromLong(i + 1);    if (o == NULL)        return -1;    if (PyDict_SetItem(self->dict, key, o) < 0) {        Py_DECREF(o);        return -1;    }    Py_DECREF(o);}

int PyDict_Merge(PyObject a, PyObject b, int override) 將b字典內的資料,加入到a字典中去,override表示是否覆蓋資料,如果override為true則覆蓋資料,反之亦然

int PyDict_Update(PyObject a, PyObject b) 把b字典中的資料加入到a字典中,如果a和b出現相同的key,則b直接更新a中key對應的值

執行個體

標頭檔

//// Created by lanyulei on 18-9-5.//#ifndef PRINT_DEMO1_PYDCIT_H#define PRINT_DEMO1_PYDCIT_H#include <stdio.h>#include <stdlib.h>#include <string.h>#include <Python.h>#include "print.h"// 字典練習void test_dict();#endif //PRINT_DEMO1_PYDCIT_H

源檔案

//// Created by lanyulei on 18-9-5.//#include "pyDcit.h"void test_dict(){    //建立dict    PyObject* py_dict_1 = PyDict_New();    //檢查PyObject是不是一個字典    int ret = PyDict_Check(py_dict_1);    if (ret)    {        printf("is dict\n");    }    else    {        printf("is not dict\n");    }    PyObject *py_key_account_id = Py_BuildValue("s", "account_id");    PyObject *py_value_account_id = Py_BuildValue("i", 1238);    //向dict添加一個key-value    PyDict_SetItem(py_dict_1, py_key_account_id, py_value_account_id);    PyObject *py_value_account_name = Py_BuildValue("s", "mono");    PyDict_SetItemString(py_dict_1, "account_name", py_value_account_name);    PyObject *py_key1 = Py_BuildValue("i", 1);    PyObject *py_key1_value = Py_BuildValue("i", 2399);    PyDict_SetItem(py_dict_1, py_key1, py_key1_value);    //擷取字典的大小    int dict_len = PyDict_Size(py_dict_1);    printf("dict_len=%d\n", dict_len);    print_pyobject(py_dict_1);    //從字典刪除一個key    PyDict_DelItem(py_dict_1, py_key_account_id);    printf("del item: py_key_account_id--------------------------\n");    print_pyobject(py_dict_1);    //刪除一個不存在的key    PyObject *py_not_existing_key = Py_BuildValue("s", "name");    PyDict_DelItem(py_dict_1, py_not_existing_key);    printf("del item: py_not_existing_key------------------\n");    print_pyobject(py_dict_1);    //-------------------------------------------------------    //PyDict_DelItemString(py_dict_1, "account_name");    //printf("del item: account_name -----------------\n");    //print_pyobject(py_dict_1);    PyObject *py_key_account_name = Py_BuildValue("s", "account_name");    //從字典中擷取一個key-value    PyObject *py_value1 = PyDict_GetItem(py_dict_1, py_key_account_name);    printf("get item: account_name-----------------------\n");    print_pyobject(py_value1);    printf("\n");    //從字典中擷取一個key-value    PyObject *py_value2 = PyDict_GetItemString(py_dict_1, "account_name");    printf("get item string: account_name -------------------\n");    print_pyobject(py_value2);    printf("\n");    //-----------------------------------------------------------    //從字典中擷取所有key-value對    PyObject *py_items = PyDict_Items(py_dict_1);    printf("get items --------------------------\n");    print_pyobject(py_items);    printf("\n");    //--------------------------------------    //從字典中擷取所有key    PyObject *py_keys = PyDict_Keys(py_dict_1);    printf("get keys -------------------------\n");    print_pyobject(py_keys);    printf("\n");    //------------------------------------------------    //從字典擷取所有值    PyObject *py_values = PyDict_Values(py_dict_1);    printf("get values -----------------------\n");    print_pyobject(py_values);    printf("\n");    //------------------------------------------------------    //遍曆字典    PyObject *key, *value;    Py_ssize_t pos = 0;    printf("dict next -------------------\n");    while (PyDict_Next(py_dict_1, &pos, &key, &value))    {        print_pyobject(key);        printf("=");        print_pyobject(value);        printf("\n");    }    //---------------------------------------------    PyObject *py_dict_2 = PyDict_New();    PyObject *py_key21 = Py_BuildValue("i", 101);    PyObject *py_key21_value = Py_BuildValue("i", 60000);    PyDict_SetItem(py_dict_2, py_key21, py_key21_value);    PyObject *py_value_level = Py_BuildValue("i", 30);    PyDict_SetItemString(py_dict_2, "account_level", py_value_level);    PyObject *py_value_account_name2 = Py_BuildValue("s", "myname");    PyDict_SetItemString(py_dict_2, "account_name", py_value_account_name2);    printf("dict_2 items --------------------\n");    print_pyobject(py_dict_2);    //把py_dict_2的所有資料添加到py_dict_1    PyDict_Merge(py_dict_1, py_dict_2, 0);    printf("dict merge: override=0, -----------------\n");    print_pyobject(py_dict_1);    //----------------------------------------    PyObject *py_dict_3 = PyDict_New();    PyObject *py_value_score = Py_BuildValue("i", 10000);    PyDict_SetItemString(py_dict_3, "account_score", py_value_score);    PyObject *py_value_account_name3 = Py_BuildValue("s", "sujin");    PyDict_SetItemString(py_dict_3, "account_name", py_value_account_name3);    //將py_dict_3的所有資料添加到py_dict_1, 這個api相當於PyDict_Merge第三個參數為1的情況.    PyDict_Update(py_dict_1, py_dict_3);    printf("dict update ----------------------\n");    print_pyobject(py_dict_1);    //---------------------------------------------    const char *check_key = "account_name";    PyObject *py_check_key = Py_BuildValue("s", check_key);    //在字典中檢查是否存在這個key    ret = PyDict_Contains(py_dict_3, py_check_key);    if (ret)    {        printf("has key: %s\n", check_key);    }    else    {        printf("no key: %s\n", check_key);    }    //-------------------------------------------------    //清空字典的所有資料    PyDict_Clear(py_dict_3);    printf("dict clear ---------------------\n");    print_pyobject(py_dict_3);}
根據資料類型列印資料的方法

標頭檔

//// Created by lanyulei on 18-9-1.//#ifndef PRINT_DEMO1_PRINT_H#define PRINT_DEMO1_PRINT_H#include <Python.h>void print_pyobject(PyObject *py_obj);#endif //PRINT_DEMO1_PRINT_H

源檔案

//// Created by lanyulei on 18-9-1.//#include "print.h"#include <stdio.h>#include <string.h>#include <stdlib.h>// Python 中的浮點類型, 都是doublevoid print_pyobject(PyObject *py_obj){    if (py_obj == NULL){        printf("NULL");        return;    }    if (PyInt_Check(py_obj)){        // int        int ival = PyInt_AsLong(py_obj);        printf("我是整型,ival = %d\n", ival);    } else if (PyLong_Check(py_obj)){        // long        long long lval = PyLong_AsLongLong(py_obj);        printf("我是長整型,lval = %lld\n", lval);    } else if (PyFloat_Check(py_obj)){        // float/double        double fval = PyFloat_AS_DOUBLE(py_obj);        printf("我是浮點類型,fval = %lf\n", fval);    } else if (PyBool_Check(py_obj)){        // bool        int bval = PyInt_AsLong(py_obj);        if (bval == 1){            printf("我是布爾類型,bval = true\n");        }else {            printf("我是布爾類型,bval = false\n");        }    } else if (PyString_Check(py_obj)){        // 不包含中文的字串        char *str = PyString_AsString(py_obj);        printf("我是不包含中文的字串,str = %s\n", str);    } else if (PyUnicode_Check(py_obj)){        // unicode 含有中文的字串        // 首先將unicode轉成utf-8        PyObject *py_utf8 = PyUnicode_AsUTF8String(py_obj);        char *ustr = PyString_AsString(py_utf8);        printf("我是unicode,ustr = %s\n", ustr);    } else if (PyList_Check(py_obj)){        // Python list        printf("我是列表,");        printf("[\n");        for (int i = 0;i < PyList_Size(py_obj); i++){            PyObject *py_data = PyList_GetItem(py_obj, i);            print_pyobject(py_data);        }        printf("]\n");    } else if (PyTuple_Check(py_obj)){        // Python tuple        printf("我是元組,");        printf("(\n");        for (int i = 0;i < PyTuple_Size(py_obj); i++){            PyObject *py_data = PyTuple_GetItem(py_obj, i);            print_pyobject(py_data);        }        printf(")\n");    } else if (PyDict_Check(py_obj)){        // Python dict        PyObject *key, *value;        Py_ssize_t pos = 0;        printf("我是字典,");        printf("{\n");        while (PyDict_Next(py_obj, &pos, &key, &value)) {            print_pyobject(key);            printf("=");            print_pyobject(value);        }        printf("}\n");    }}

main函數

#include <stdio.h>#include <stdlib.h>#include <string.h>int main() {    // 初始化Python虛擬機器    Py_Initialize();    // 判斷Python虛擬機器是否成功    if (Py_IsInitialized() == 0){        printf("fal to initialize Python\n");        return -1;    }    printf("server start\n");    // 退出Python虛擬機器    Py_Finalize();    return 0;}

Python C API 使用詳解(二)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.