好友
阅读权限10
听众
最后登录1970-1-1
|
补一个例子,模拟print输出序列,虽然我们可以通过调用PyObject_Str轻松的获取到输出某个对象输出的样子,但是为了联系我自己也写了个类似的,遍历输出每一个元素。
这是Python代码:
[Python] 纯文本查看 复制代码
import PrintSequence as CPrintSequence
##判断是否是可迭代对象(这里不对str,bytes进行判断)
isSequence = lambda sqc:(isinstance(sqc, list) or\
isinstance(sqc, tuple) or\
isinstance(sqc, dict) or\
isinstance(sqc, set))
def PyPrintSequence(sqc):
left = ""
right = ""
isDict = False
##是列表
if isinstance(sqc, list):
left='['; right=']'
if isinstance(sqc, tuple):
left='('; right=')'
if isinstance(sqc, dict) or isinstance(sqc, set):
left='{'; right='}'; isDict=True if isinstance(sqc,dict) else False
##列表,元组
if isinstance(sqc, list) or isinstance(sqc, tuple):
print(left, end='')
for index in range(len(sqc)):
v = sqc[index]
##是列表,元组,字典,集合中的一个类型,继续向里面迭代
if isSequence(v):
PyPrintSequence(v)
print(',', end='')
else:
#有可能v是字符串
StringSybmol = "\"" if isinstance(v,str) else ""
print(StringSybmol,v.__str__(),StringSybmol, end=',')
#退一格再打印,因为多了个逗号
print('\b', end=right)
#结束本次递归
return None
##字典,集合
if isinstance(sqc, dict) or isinstance(sqc, set):
print(left, end='')
for k in sqc:
#先打印键名,(冒号的打印取决于当前的sqc是字典还是集合)
#集合中的元素有可能是isSequence提及的可迭代对象
v = k;
if isDict:
print('\''+k+'\'', end=':')
v = sqc[k]
##是列表,元组,字典,集合中的一个类型,继续向里面迭代
if isSequence(v):
PyPrintSequence(v)
print(',', end='')
else:
StringSybmol = "\"" if isinstance(v,str) else ""
print(StringSybmol,v.__str__(),StringSybmol, end=',')
print('\b', end=right)
return None
##不是isSequence提及的可迭代对象,直接调用其__str__魔法方法获得字符串对象
print(sqc, end=',')
myIter = (520,[1,b'\x11\x12\x13',3.14, "biu~~~", {6,2,3,1}, {"c":123,"b":("qwe","zxvc",),"lambda":isSequence}, 233],[[111]],666)
print("系统提供的打印:\n", myIter)
print("咱们自己的打印:\n")
PyPrintSequence(myIter)
print('\n')
print("咱们自己的C模块:")
CPrintSequence.Print(myIter)
print(input())
上面的模块是由下面的代码编译出来的:
[C++] 纯文本查看 复制代码 //filename: PrintSequence..cpp
#include <iostream>
#include "Python.h"
using namespace std;
#pragma comment(lib, "Python37.lib")
/* std c++11 */
/* 判断是不是list、tuple、dict、set中的一种 */
auto isSequence = \
[=](PyObject* sqc)->bool{
return ((PyList_Check(sqc)) || \
(PyTuple_Check(sqc))|| \
(PyDict_Check(sqc)) || \
(PySet_Check(sqc)));
};
bool PrintValue(PyObject* py_str, bool isString=false) {
wchar_t* wc_str;
char syssymbol = 0;
Py_ssize_t tsize;
wc_str = PyUnicode_AsWideCharString(py_str, &tsize);
if (!wc_str)
return false;
if (isString)
syssymbol='\"';
wcout << syssymbol << wc_str << syssymbol;
return true;
}
static PyObject* RealPrintFunction(PyObject* sqc) {
/* 左闭合符号和右闭合符号 */
char left='\0', right='\0';
/* 列表 */
if (PyList_Check(sqc))
{ left='['; right=']'; }
/* 元组 */
if (PyTuple_Check(sqc))
{ left='('; right=')'; }
/* 遍历列表或元组 */
if (PyList_Check(sqc) || PyTuple_Check(sqc)) {
/* 先输出符号 */
cout.put(left);
//获取长度
Py_ssize_t length = PyList_Check(sqc) ? PyList_Size(sqc) : PyTuple_Size(sqc);
//循环遍历
for (Py_ssize_t index=0; index < length; index++) {
//获取元素
PyObject* v = PyList_Check(sqc) ? PyList_GetItem(sqc, index) : PyTuple_GetItem(sqc, index);
if (v) {
if (isSequence(v)) {
//递归遍历
RealPrintFunction(v);
cout.put(',');
} else {
PyObject* py_str = PyObject_Str(v);
if (py_str) {
PrintValue(py_str, PyUnicode_Check(v));
cout.put(',');
}
Py_XDECREF(py_str);
}
}
}
cout.put('\b');
cout.put(right);
Py_RETURN_NONE;
}
bool isDict=false;
/* 利用逻辑短路和逻辑断路判断并且修改isDict的值 */
/* 字典和集合 */
if (PySet_Check(sqc) || (PyDict_Check(sqc) && (isDict=true))) {
left='{'; right='}';
cout.put(left);
/* 获取迭代器 */
PyObject* myiterator = PyObject_GetIter(sqc);
if (myiterator) {
PyObject* k;
while (NULL != (k = PyIter_Next(myiterator))) {
PyObject* v = k;
PyObject* py_str = PyObject_Str(v);
if (!py_str) {
Py_XDECREF(k);
continue;
}
/* 如果是字典就输出键和冒号 */
if (isDict) {
if (!PrintValue(py_str, PyUnicode_Check(v))) {
Py_XDECREF(py_str);
continue;
}
cout.put(':');
v = PyDict_GetItem(sqc, k);
//此时键已经作废
Py_XDECREF(k);
if (!v)
continue;
py_str = PyObject_Str(v);
if (!py_str)
continue;
}
if (isSequence(v)) {
//递归遍历
RealPrintFunction(v);
cout.put(',');
} else {
PrintValue(py_str, PyUnicode_Check(v));
Py_XDECREF(py_str);
cout.put(',');
/* 如果是字典那么之前k已经作废(因为当是集合时v=k) */
if (!isDict)
Py_XDECREF(v);
}
}
}
cout.put('\b');
cout.put(right);
}
Py_RETURN_NONE;
}
static PyObject* PrintSequence_Print(PyObject*self, PyObject* args) {
PyObject* real_iterator_object;
/* 检查是否是对象 */
if (!PyArg_ParseTuple(args, "O", &real_iterator_object))
return NULL;
/* 检查是否是可迭代对象 */
if (PyIter_Check(real_iterator_object)) {
return NULL;
}
/* 调用C函数 */
PyObject* ret = RealPrintFunction(real_iterator_object);
cout.put('\n');
return ret;
}
static PyMethodDef PrintSequenceMethods[] = {
{"Print", PrintSequence_Print, METH_VARARGS, "Walking down Sequence"},
{NULL}
};
static PyModuleDef PrintSequenceModule = {
PyModuleDef_HEAD_INIT,
"PrintSequence",
"It\'s magic function called \'Print\' in PrintSequence!",
-1,
PrintSequenceMethods,
NULL, NULL, NULL, NULL
};
PyMODINIT_FUNC PyInit_PrintSequence(void) {
return PyModule_Create(&PrintSequenceModule);
}
这是输出结果(有点诡异):
[Shell] 纯文本查看 复制代码
λ python PrintSequence.py
系统提供的打印:
(520, [1, b'\x11\x12\x13', 3.14, 'biu~~~', {1, 2, 3, 6}, {'c': 123, 'b': ('qwe', 'zxvc'), 'lambda': <function <lambda> at 0x00C8F8A0>}, 233], [[111]], 666)
咱们自己的打印:
( 520 ,[ 1 , b'\x11\x12\x13' , 3.14 ," biu~~~ ",{ 1 , 2 , 3 , 6 },{'c': 123 ,'b':(" qwe "," zxvc "),'lambda': <function <lambda> at 0x00C8F8A0> }, 233 ],[[ 111 ]], 666 )
咱们自己的C模块:
( 5 2 0 ,[ 1 , b ' \ x 1 1 \ x 1 2 \ x 1 3 ' , 3 . 1 4 ," b i u ~ ~ ~ " ,{ 1 , 2 , 3 , 6 },{" c " : 1 2 3 ," b " :(" q w e " ," z x v c " )," l a m b d a " : < f u n c t i o n < l a m b d a > a t 0 x 0 0 C 8 F 8 A 0 > }, 2 3 3 ],[[ 1 1 1 ]], 6 6 6 )
|
|