繁体   English   中英

Python 类和 __iter__

[英]Python class and __iter__

在 Python 类中使用__iter__函数有什么好处?

在下面的代码中,我只是设置了两个简单的类。 第一个类接受一个列表作为参数,我可以在不使用__iter__函数的情况下遍历这个列表。 代码的第二位使用__iter__函数来循环列表。

当已经有方法循环类中的内容时,使用__iter__有什么好处?

EG 1: no __iter__


class test_class:
    def __init__(self, list):
        self.container_list = list

    def print (self):
        a = self.container_list
        return a

test_list = test_class([1,2,3,4,5,6,7])

x = test_class.print(test_list)

for i in x:
    print (i)



EG 2: yes __iter__

class list_using_iter:
    def __init__(self):
        self.list = [1,2,3,4]
        self.index = -1

    def __iter__(self):
        return self

    def __next__(self):
        self.index += 1
        if self.index == len(self.list):
            raise StopIteration
        return self.list [self.index]

r = list_using_iter()
itr = iter(r)

print(next(itr))
print(next(itr))
print(next(itr))
print(next(itr))

print(next(itr)) # Raises the exception!

您的第一个示例不可迭代,但包含一个可迭代的属性。 您的第二个示例是可迭代的,但您只需“跟随”另一个可迭代对象即可进行迭代。 这是一个迭代的例子,它本身做了更多的工作:

import itertools

class Fibs:
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def __iter__(self):
        a = self.a
        b = self.b
        while True:
            yield a
            a, b = b, a + b

real_fibs = Fibs(0,1)

for i in itertools.islice(real_fibs, 10):
    print(i)

Fibs.__iter__不是简单地反刍从其他值的__iter__方法获得的值; 它根据需要计算并产生新的价值。


实际上,前面是一个知道如何创建自己的迭代器的类的示例,而不是让每个对象都可迭代。 这是一个定义next本身的版本。

class Fibs:
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def __iter__(self):
        return self

    def __next__(self):
        rv = self.a
        self.a, self.b = self.b, self.a + self.b
        return rv

在这两种情况下,循环工作都是因为__iter__ 在您的第一个示例中,您的打印函数返回一个循环。 for关键字的实现将调用__iter__ (或 C 实现中的相应槽,因为所涉及的代码在 C 解释器中)以循环遍历列表。

在你的第二个例子中,你可以写

for elt in r:
    print(elt)

它会在内部调用__iter__来实现 for 循环。

一般来说,您倾向于直接使用for而不是iternext 直接使用iternext是当您生成一个将生成迭代器的回调函数时,或者当您根据另一个迭代器定义一个迭代器时。

__iter__何时应该编写自己的__iter__或返回一些进行自己迭代的对象,这一切都取决于您想要什么功能。 例如,你的第一个类更强大,因为两个人可以同时迭代列表。 在您的第二个类中,由于您将索引存储在类本身中,因此一次只有一个人可以成功使用迭代器。 但是,如果您有足够复杂的行为,那么您定义自己的__iter__的第二种方法可能是有意义的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM