Python 2.7跟踪已打印的内容

时间:2013-08-08 21:24:22

标签: python logging python-2.7

我正在为我的学生编写代码检查员(我是导师)。该项目是他们编写了一个使用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中实现同样的功能。

3 个答案:

答案 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

(您可能希望将其包含在捕捉和隐藏异常的内容中,但这应该足以让您了解。)