美文网首页大数据 爬虫Python AI Sql互联网科技程序员
扩展和嵌入 Python 之重定向输出与编译

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

作者: 919b0c54458f | 来源:发表于2019-04-07 14:41 被阅读11次

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

    Python学习群:556370268,有大牛答疑,有资源共享!是一个非常不错的交流基地!欢迎喜欢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 函数会有警告。还有就是在初始化模块时有一些改动,将系统的标准输出与标准错误输出做了重定向。运行之前的程序结果如图:

    image

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

    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图示:

    image

    Python源文件:

    image

    点击编译按钮运行结果:

    image

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

    image

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

    相关文章

      网友评论

        本文标题:扩展和嵌入 Python 之重定向输出与编译

        本文链接:https://www.haomeiwen.com/subject/nyrsiqtx.html