如何调试使用生成器和迭代器的代码?我发现添加带有for
语句的print
循环会占用生成器/迭代器,因此会破坏其余的代码。是否有可能检查内容"没有消耗元素的生成器/迭代器?
更具体地说,我有这样的事情:
result = map(func, x)
现在我想看看result
是什么。我还希望通过将函数应用于result
中的每个元素来查看返回的值。在我的实际代码中,我得到了result
中的元素,它给出了这个函数的最小值:
best = min(result, key=my_key)
现在min()
非常方便,但我的行为不正确,需要找出原因。我可以使用哪些工具来调试这样的东西?
P.S。我正在使用PyCharm。我对交互式调试器非常熟悉,但仍无法弄清楚如何查看此处发生的所有事情。
答案 0 :(得分:3)
如果要打印函数参数的值以及返回的值,可以使用包装原始函数的包装器并打印传递到func
或my_key
的值,以及他们的回报值。像
def debug_func(func):
@functools.wraps(func)
def wrapper(*a, **kw):
print('Arguments', a, kw)
rv = func(*a, **kw)
print('Return value', repr(rv))
return rv
return wrapper
一个用法示例:
>>> list(map(debug_func(len), ['foo', 'bar', 'foobar']))
Arguments ('foo',) {}
Return value 3
Arguments ('bar',) {}
Return value 3
Arguments ('foobar',) {}
Return value 6
[3, 3, 6]
或者
>>> min(['foo', 'bar', 'foobar'], keydebug_func(len))
Arguments ('foo',) {}
Return value 3
Arguments ('bar',) {}
Return value 3
Arguments ('foobar',) {}
Return value 6
'foo'
类似的方法也可以用于迭代器:
def debug_iter(iterator):
while True:
value = next(iterator)
print('Iterator yielded', repr(value))
yield value
用法:
>>> [i for i in debug_iter(i ** 2 for i in range(5)) if i % 2]
Iterator yielded 0
Iterator yielded 1
Iterator yielded 4
Iterator yielded 9
Iterator yielded 16
[1, 9]