我正在为我的学生编写代码检查员(我是导师)。该项目是他们编写了一个使用print
关键字打印特定字符串的函数。我希望能够通过存储和匹配列表(或类似的东西)来测试他们打印的内容。基本设置是:
def checker():
#run user code
do some other things like save and check error messages etc
现在,在这个checker
函数的某个地方,我希望能够跟踪打印的内容。在Javascript中,我能够做到这样的事情:
var logs = [];
var hold_logger = console.log //saves the console.log so nothing gets ruined
console.log = function (x) { logs.push(x) };
现在,当我运行学生代码而不是打印到控制台时,它会将值推送到logs
。我想在Python 2.7中实现同样的功能。
答案 0 :(得分:6)
您可以为sys.stdout
分配不同的类文件对象;打印的任何内容都会写入该对象。
您可以使用io.BytesIO()
object替换stdout
:
import sys
from io import BytesIO
orig_stdout, sys.stdout = BytesIO()
io
是Python 3中更新,更强大的I / O库,也可以在Python 2中使用; io.BytesIO()
是StringIO.StringIO()
的更强大版本。
然后,您可以通过调用sys.stdout.getvalue()
来检查打印的内容;完成后,您可以从orig_stdout
恢复。
演示:
>>> import sys
>>> from io import BytesIO
>>> orig_stdout, sys.stdout = sys.stdout, BytesIO()
>>> print 'Hello world!'
>>> output = sys.stdout.getvalue()
>>> sys.stdout = orig_stdout
>>> output
'Hello world!\n'
请注意,我从之前的参考资料中恢复了sys.stdout
。您还可以使用sys.__stdout__
,提供其他内容,无需替换sys.stdout
;保存对sys.stdout
指向现在的引用更安全。
答案 1 :(得分:1)
这是一种方法 - 您可以使用自定义输出文件对象替换标准输出文件对象:
import sys
# A very basic logging class (it should really implement all the file object methods, but for your purposes, this will probably suffice.
class basicLogger:
def __init__(self):
self.log = []
def write(self, msg):
self.log.append(msg)
def writelines(self, msgs):
for msg in msgs:
self.log.append(msg)
log = basicLogger()
# Replaces the default output file object with your logger
sys.stdout = log
def checker():
#run user code
print "hello!"
print
print "I am a student!"
checker()
# This replaces the original output file object.
sys.stdout = sys.__stdout__
print "Print log:"
for msg in log.log:
print "\t", msg,
输出:
Print log:
hello!
I am a student!
答案 2 :(得分:0)
与Java相同的Python就是用自定义文件类对象替换sys.stdout
。
当然,这不会只是抓住他们print
;它还会捕获它们sys.stdout.write
,或者根据它们的设置,它们可能是logging.log
或它们运行的子过程的输出等等。但是实际上没有办法解决这个问题,因为{{1不是你可以替换的函数。 (当然,如果你教他们3.x,那将是一个不同的故事。)
但是,根本不这样做可能更简单。只需从Python外部捕获标准输出。例如:
print
或者,如果您坚持,请在Python中使用for student in student??.py:
python ${student} > ${student}.out
执行相同的操作:
subprocess
(您可能希望将其包含在捕捉和隐藏异常的内容中,但这应该足以让您了解。)