我有一個包含Python語句的文件,我想以這種方式運行Python,以便打印到stdout,如果這些命令在REPL中運行,將顯示什麼內容。將命令放入Python REPL
例如,如果該文件是
1 + 4
'a' + 'b'
然後輸出應該是
>>> 1 + 4
5
>>> 'a' + 'b'
'ab'
有沒有辦法做到這一點?
我有一個包含Python語句的文件,我想以這種方式運行Python,以便打印到stdout,如果這些命令在REPL中運行,將顯示什麼內容。將命令放入Python REPL
例如,如果該文件是
1 + 4
'a' + 'b'
然後輸出應該是
>>> 1 + 4
5
>>> 'a' + 'b'
'ab'
有沒有辦法做到這一點?
您可以使用從pexpect
replwrap
要實現這一目標,甚至有一個python
方法:
from pexpect import replwrap
with open("commands.txt", "r") as f:
commands = [command.strip() for command in f.readlines()]
repl = replwrap.python()
for command in commands:
print ">>>", command
print repl.run_command(command),
將返回:
python replgo.py
>>> 1 + 4
5
>>> 'a' + 'b'
'ab'
你需要獲得最新版本的pexpect。
一些AST魔法可以幫助在這裏:
import ast
import itertools
def main():
with open('test.txt', 'r') as sr:
parsed = ast.parse(sr.read())
sr.seek(0)
globals_ = {}
locals_ = {}
prev_lineno = 0
for node in ast.iter_child_nodes(parsed):
source = '\n'.join(itertools.islice(sr, 0, node.lineno - prev_lineno))[:-1]
print('>>> {}'.format(source))
if isinstance(node, ast.Expr):
print(eval(source, globals_, locals_))
else:
exec(source, globals_, locals_)
prev_lineno = node.lineno
if __name__ == '__main__':
main()
輸入:
1 + 4
'a' + 'b'
a = 1
a
輸出:
>>> 1 + 4
5
>>> 'a' + 'b'
ab
>>> a = 1
>>> a
1
這裏做的事情是找到每個起始和終止行號通過使用ast
模塊解析源,然後調用eval
或exec
,具體取決於它是聲明還是表達式。
上下文保存在globals_
和locals_
。
您可以通過使用一些python沙盒來執行eval
和exec
以更安全。
(不那麼)快速(大部分)髒了,用code模塊:
import sys
import code
infile = open('cmd.py')
def readcmd(prompt):
line = infile.readline()
if not line:
sys.exit(0)
print prompt,line.rstrip()
return line.rstrip()
code.interact(readfunc=readcmd)
很多需要改進的地方,但它的晚在這裏。不管怎麼說,例如:
sh$ cat cmd.py
1 + 4
'a' + 'b'
1/0
def f(x):
return x*2
f(3)
sh$ python console.py
Python 2.7.3 (default, Mar 13 2014, 11:03:55)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> 1 + 4
5
>>> 'a' + 'b'
'ab'
>>>
>>> 1/0
Traceback (most recent call last):
File "<console>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero
>>>
>>> def f(x):
... return x*2
...
>>> f(3)
6
您可以將輸入管道輸入到pythons「code」模塊。它會顯示輸出,但不會顯示輸入。
$ echo '1 + 1' | python -m code
Python 2.7.10 (v2.7.10:15c95b7d81dc, May 23 2015, 09:33:12)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> 2
Windows? * n * x?跨平臺? – 2014-08-28 21:05:37
Linux,但我真的希望有一個跨平臺的方法。 – 2014-08-28 21:25:43