前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >扩展和嵌入python之重定向输出与编译

扩展和嵌入python之重定向输出与编译

作者头像
用户5908113
发布2019-07-30 15:03:23
5820
发布2019-07-30 15:03:23
举报
文章被收录于专栏:Pou光明Pou光明

在小长假的前一天要总结下最近的收获。

Ok,按照之前两篇嵌入和扩展python的文章来操作的话,现在已经可以定义自己的模块、在运行时获取异常信息。那么问题来了,在编写程序的过程中,难免有语法错误,如何在运行程序前检查这些错误呢?在编写大量python程序时,可以使用IDE辅助检查,也可以使用静态语法检查工具。如果我们自己做python编辑器,肯定要有语法检查的,总不能在运行时一直报语法错误,那会让人崩溃的。。。还有今天要分享的另一个话题,如何在嵌入的解释器中重新定向print()输出,这个在操作上也是比较简单。有了这两个骚操作,基础的功能就基本完成了。别高兴太早,之后还有更头疼的事情呢,比如,python解释器被嵌入到了一个线程里面,然后你要中断此时线程里面的操作。。。

重定向的功能实现起来比较方便,先贴这部分程序:

static PyObject *

aview_write(PyObject *self, PyObject *args)

{

(void)self;

char *what;

if (!PyArg_ParseTuple(args, "s", &what))

{

return NULL;

}

// QString str(what);

printf("--%s", what);

return Py_BuildValue("");

}

static PyObject*

aview_flush(PyObject* self, PyObject* args)

{

(void)self;

(void)args;

// no-op

return Py_BuildValue("");

}

static PyMethodDef MathMethods[] = {

{"add", add, METH_VARARGS,"add."},

{"write", aview_write, METH_VARARGS,"aview_write."},

{"flush", aview_flush, METH_VARARGS,"aview_flush."},

{NULL, NULL, 0, NULL}

};

static PyModuleDef MathModule = {

PyModuleDef_HEAD_INIT, "dahe", NULL, -1, MathMethods,

NULL, NULL, NULL, NULL

};

static PyObject*

PyInit_math(void)

{

PyObject* m = PyModule_Create(&MathModule);

PySys_SetObject("stdout", m);

PySys_SetObject("stderr", m);

return m;

}

相比之前的程序,又添加了write和flush的函数,只添加write函数会有警告。还有就是在初始化模块时有一些改动,将系统的标准输出与标准错误输出做了重定向。运行之前的程序结果如图:

这样我们静态检查的报错信息也就可以获得了。接下来介绍编译的方法。

Python的py_compile模块提供了一种将源文件生成字节代码的方法,我们正是利用它的编译功能去完成我们的静态语法检查。

#define COMPILEFILEPATH "os.chdir('/root/Python/Article/redirect/pythonSource/')"

#define PYTHONPYCFILE "/root/Python/Article/redirect/compileDirectory/"

void Widget::on_pbn_compilePython_clicked()

{

qDebug() << "compile python !";

PyImport_AppendInittab("dahe", &PyInit_math);

Py_Initialize();

if (!Py_IsInitialized())

{

qDebug() << "inital faild!";

}

PyRun_SimpleString("import os");

PyRun_SimpleString(COMPILEFILEPATH);

PyRun_SimpleString("import dahe");

PyRun_SimpleString("import py_compile");

QString execFileName = "dhTest";

QString pycFilePath = QString("py_compile.compile('%1.py','%2%1.pyc')").arg(execFileName).arg(PYTHONPYCFILE);

char* ch;

QByteArray ba = pycFilePath.toLatin1();

ch=ba.data();

PyRun_SimpleString(ch);

Py_Finalize();

}

上方是两个路径的宏,之前源代码一直存放在可执行程序的目录下,那也是默认的python工作目录,现在我们改变了工作目录。由于编译会生成字节代码文件,我们也为这些文件指定了路径。整个编译的代码是一个按钮的槽函数。我们写入错误的字符,运行编译的功能,观察效果。

UI图示:

Python源文件:

点击编译按钮运行结果:

点击运行按钮,此时是动态检查结果:

这样我们就实现了在运行前检查语法错误的效果了。

程序还有很多不完善的地方,希望大家不吝赐教。多谢。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-04-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Pou光明 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档