我正在制作一个简单的测试函数,通过从文件中读取要评估的表达式和预期结果来断言我正在开发的解释器的输出是正确的,这与 python 的 doctest 非常相似。这是针对方案的,因此输入文件的示例是
> 42
42
> (+ 1 2 3)
6
我对可以解析此类文件的函数的第一次尝试如下所示,它似乎按预期工作:
def run_test(filename):
interp = Interpreter()
response_next = False
num_tests = 0
with open(filename) as f:
for line in f:
if response_next:
assert response == line.rstrip('\n')
response_next = False
elif line.startswith('> '):
num_tests += 1
response = interp.eval(line[2:])
response = str(response) if response else ''
response_next = True
print "{:20} Ran {} tests successfully".format(os.path.basename(filename),
num_tests)
我想通过删除 response_next
标志来稍微改进它,因为我不喜欢这样的标志,而是在 elif
block 中读取下一行使用 next(f)
。关于我在 freenode 的 IRC 中询问的问题,我有一个无关的小问题。我得到了我想要的帮助,但我也得到了使用 f.readlines()
的建议,然后在结果列表上使用索引。 (我还被告知我可以在 itertools
中使用 groupby()
来生成成对线,但我稍后会研究这种方法。)
现在回答这个问题,我很好奇为什么这种方法会更好,但我在火车上的互联网连接不稳定,我无法提问,所以我会在这里提问。为什么使用 readlines()
读取所有内容而不是在动态读取时解析每一行会更好?
我真的很想知道,因为我的感觉恰恰相反,我认为一次解析一行似乎更干净,这样一切都一次性完成。我通常避免在 Python 的数组中使用索引,而更喜欢使用迭代器和生成器。如果这是一个主观意见,也许不可能回答和猜测这个人在想什么,但如果有一些一般性的建议,我会很高兴听到。
最佳答案
迭代处理输入肯定比一次读取整个输入更 Pythonic;例如,如果输入是控制台,这将起作用。
支持读取整个数组和索引的一个论据是,当与 for
循环结合使用时,使用 next(f)
可能不清楚;那里的选项要么用 while True
替换 for
循环,要么完整记录您正在 f 上调用
在循环内:next
try:
while True:
test = next(f)
response = next(f)
except StopIteration:
pass
正如 Jonas 建议的那样,您可以通过将输入自身压缩来完成此操作(如果您确定输入将始终包含测试/响应/测试/响应等行):
for test, response in zip(f, f): # Python 3
for test, response in itertools.izip(f, f): # Python 2
关于python - 将 readlines() 与索引一起使用或即时解析行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11432911/