擴展和嵌入 Python 之重定向輸出與編譯

擴展和嵌入 Python 之重定向輸出與編譯

在編寫程序的過程中,難免有語法錯誤,如何在運行程序前檢查這些錯誤呢?在編寫大量 python 程序時,可以使用 IDE 輔助檢查,也可以使用靜態語法檢查工具。如果我們自己做 python 編輯器,肯定要有語法檢查的,總不能在運行時一直報語法錯誤,那會讓人崩潰的。。。還有今天要分享的另一個話題,如何在嵌入的解釋器中重新定向 print() 輸出,這個在操作上也是比較簡單。有了這兩個騷操作,基礎的功能就基本完成了。別高興太早,之後還有更頭疼的事情呢,比如, python 解釋器被嵌入到了一個線程裡面,然後你要中斷此時線程裡面的操作。。。

記得關注小編後私信【學習】領取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 之重定向輸出與編譯


這樣我們靜態檢查的報錯信息也就可以獲得了。接下來介紹編譯的方法。

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 之重定向輸出與編譯

Python源文件:

擴展和嵌入 Python 之重定向輸出與編譯

點擊編譯按鈕運行結果:

擴展和嵌入 Python 之重定向輸出與編譯

點擊運行按鈕,此時是動態檢查結果:

擴展和嵌入 Python 之重定向輸出與編譯

這樣我們就實現了在運行前檢查語法錯誤的效果了。

記得關注小編後私信【學習】領取Python學習教程哦。

擴展和嵌入 Python 之重定向輸出與編譯


分享到:


相關文章: