调试生成器和迭代器

时间:2016-12-27 05:15:06

标签: python debugging pycharm

如何调试使用生成器和迭代器的代码?我发现添加带有for语句的print循环会占用生成器/迭代器,因此会破坏其余的代码。是否有可能检查内容"没有消耗元素的生成器/迭代器?

更具体地说,我有这样的事情:

result = map(func, x)

现在我想看看result是什么。我还希望通过将函数应用于result中的每个元素来查看返回的值。在我的实际代码中,我得到了result中的元素,它给出了这个函数的最小值:

best = min(result, key=my_key)

现在min()非常方便,但我的行为不正确,需要找出原因。我可以使用哪些工具来调试这样的东西?

P.S。我正在使用PyCharm。我对交互式调试器非常熟悉,但仍无法弄清楚如何查看此处发生的所有事情。

1 个答案:

答案 0 :(得分:3)

如果要打印函数参数的值以及返回的值,可以使用包装原始函数的包装器并打印传递到funcmy_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]