python interpreter是什么_如何写一个Python Interpreter | 学步园

最近一直在捣鼓Python,老想学别人在自己的SolidMCP之类搞一个Python Interpreter。

起初觉得很高深,就直接把将某开源软件基于Qt的Python Console实现剥离开来,成功移植到SolidMCP内。

在这个过程中发现,其实写一个蹩脚的Python Interpreter并不是太难,Piaoger决定沉下心来,研究一把,并把研究成果记录下来如下:

>> 如何写一个Python Interpreter

可以先用Python来写一个Prototype,再用C++翻译过来就是啦。

importsysimportosimportcode

redirectedOutput= r'C:\RedirectedPythonConsole.txt'

#Redirected Channel

classMyConsole:defwrite(self, input):

myFile= file(redirectedOutput, 'a')

output= '\nPython>' +input

myFile.write(output)

myFile.close()#Redirect stdout to MyConsole

defaultStdOut =sys.stdout

myConsole=MyConsole()

sys.stdout=myConsoleifos.path.exists(redirectedOutput):

os.remove(redirectedOutput)#Compile input code to code object#Run Code Object

inputCode = '2+3'interpreter=code.InteractiveInterpreter()

codeObject=interpreter.compile(inputCode)

interpreter.runcode(codeObject)

sys.stdout= myConsole

>>C++版本原型

//Demonstrates how to use Interactive Interpreter and Interactive Console

voidtestInterpreter()

{

Py_Initialize();//#load code module to use InteractiveInterpreter and InteractiveConsole//# Utilities used to emulate Python's interactive interpreter//# InteractiveConsole closely emulates the behavior of the interactive Python interpreter//# InteractiveConsole builds on InteractiveInterpreter//import code module

PyObject* module = PyImport_ImportModule("code");//Construct InteractiveInterpreter from code module

PyObject* func = PyObject_GetAttrString(module, "InteractiveInterpreter");

PyObject* args = Py_BuildValue("()");

PyObject* interpreter =PyEval_CallObject(func,args);//Provide input as code

const char* source = "2+3";

PyObject* sourceArgs = Py_BuildValue("(s)", source);

PyObject* compilefunc = PyObject_GetAttrString(interpreter, "compile");

PyObject* codeObject =PyEval_CallObject(compilefunc, sourceArgs);//run compiled bytecode

PyObject* mainModule = PyImport_AddModule("__main__");

PyObject* dict =PyModule_GetDict(mainModule);

PyObject* presult = PyEval_EvalCode((PyCodeObject*)codeObject, dict, dict);//Finally, release everything by decrementing their reference counts.//Py_DECREF(mainModule);

Py_DECREF(presult);

Py_DECREF(dict);

Py_DECREF(codeObject);

Py_DECREF(compilefunc);

Py_DECREF(sourceArgs);

Py_DECREF(interpreter);

Py_DECREF(args);

Py_DECREF(func);

Py_Finalize();

}

基本上原理就是这样的,其余的事情不外乎也搞一个sys.stdout的重定向,然后就是处理TextEdit控件的事件啦。

>> 利用InteractiveConsole直接用Python写

Python提供了一个InteractiveConsole帮我们来干这个事情,这玩意其实也是继承自InteractiveInterpreter.

那些基于PyQt的Python Console大抵就是这样干的。

# -----------------------------------------------------------------------------------------------

# Copy from ActiveState Code Recipes

# http://code.activestate.com/recipes/355319-using-codeinteractiveconsole-to-embed-a-python-she/

# -----------------------------------------------------------------------------------------------

importsysimportcodefrom code importInteractiveConsoleclassFileCacher:"Cache the stdout text so we can analyze it before returning it"

def __init__(self): self.reset()def reset(self): self.out =[]defwrite(self,line): self.out.append(line)defflush(self):

output= '\n'.join(self.out)

self.reset()returnoutputclassShell(InteractiveConsole):"Wrapper around Python that can filter input/output to the shell"

def __init__(self):

self.stdout=sys.stdout

self.cache=FileCacher()

InteractiveConsole.__init__(self)return

def get_output(self):

sys.stdout =self.cachedef return_output(self):

sys.stdout =self.stdoutdefpush(self,line):

self.get_output()#you can filter input here by doing something like

#line = filter(line)

InteractiveConsole.push(self,line)

self.return_output()

output=self.cache.flush()#you can filter the output here by doing something like

#output = filter(output)

print output #or do something else with it

return

if __name__ == '__main__':

sh=Shell()

sh.interact()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值