iter迭代无线循环错误

发布于 2022-09-02 00:04:29 字数 1457 浏览 14 评论 0

我在阅读werkzeug中实现的flask Header类的时候,碰到了这个装饰器。

def native_itermethods(names):

    def setmethod(cls, name):
        itermethod = getattr(cls, name)
        setattr(cls, 'iter%s' % name, itermethod)
        listmethod = lambda self, *a, **kw: list(itermethod(self, *a, **kw))
        listmethod.__doc__ = \
            'Like:py:meth:`iter%s`, but returns a list.' % name
        setattr(cls, name, listmethod)

    def wrap(cls):
        for name in names:
            setmethod(cls, name)
        return cls
    return wrap

这部分代码会对该类下创建一个iter开头的方法。比如get会创建出一个iterget。并把原来的get的返回值改为迭代iterget的列表。这是我理解的如果有错误请指正。

我想要对上边的装饰器进行测试验证以下是我的代码

iterget = lambda d, *arg, **kw: d.iterget(*arg, **kw)

@native_itermethods(['get'])
class A(object):

    def __init__(self):
        self._names = [('mink', '123'), ('kk', '1211')]

    def __iter__(self):
        yield iter(self._names)

    def get(self, name):
        for key, value in iterget(self):
            if key == name:
                yield key, value
                
if __name__ == '__main__':
    a = A()
    print dir(a)
    print a.get('mink')

按照我的理解上面装饰器的结果应该返回一个元组列表,但是会爆出以下错误
图片描述

是我例子写错了么还是,我对上述代码没有理解对。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

墨小沫ゞ 2022-09-09 00:04:29

首先是这个不是无限循环,而是递归超过了栈深度。

在 native_itermethods 里面,会把外面的A.get放在作为A对象iterget方法,并且用list(A.iterget)覆盖原来的A.get。在你的A.get定义里面,由于A.get已经调用了A.iterget,这其实就会是自身调用自身,会无限的递归下去,从而导致栈溢出错误。

这个函数的目的主要是方便把对象里原来的迭代器方法的名字变成itername,然后让原来的名字返回一个list后的结果。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文