標籤: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 使用詳解(二)