[英]Python class and __iter__
What are the benefits of using the __iter__
function in a Python class?在 Python 类中使用__iter__
函数有什么好处?
In the code below I am just setting up two simple classes.在下面的代码中,我只是设置了两个简单的类。 The first class takes in a list as an argument, and I am able to loop over this list without using the __iter__
function.第一个类接受一个列表作为参数,我可以在不使用__iter__
函数的情况下遍历这个列表。 The second bit of code uses the __iter__
function to loop over a list.代码的第二位使用__iter__
函数来循环列表。
What is the benefit of using __iter__
when there are already ways of looping over stuff in a class?当已经有方法循环类中的内容时,使用__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!
Your first example is not iterable, but contains an attribute that is.您的第一个示例不可迭代,但包含一个可迭代的属性。 Your second example is iterable, but you iterate simply by "following" another iterable.您的第二个示例是可迭代的,但您只需“跟随”另一个可迭代对象即可进行迭代。 Here's an example of a iterable that does more work itself:这是一个迭代的例子,它本身做了更多的工作:
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__
isn't simply regurgitating values obtained from some other value's __iter__
method; Fibs.__iter__
不是简单地反刍从其他值的__iter__
方法获得的值; it is computing and yielding new values on demand.它根据需要计算并产生新的价值。
Actually, the preceding is an example of a class that knows how to create its own iterator, rather than having each object be iterable.实际上,前面是一个知道如何创建自己的迭代器的类的示例,而不是让每个对象都可迭代。 Here's a version that defines next
itself.这是一个定义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
In both cases, the looping works because of __iter__
.在这两种情况下,循环工作都是因为__iter__
。 In your first example, your print function returns a loop.在您的第一个示例中,您的打印函数返回一个循环。 The implementation of the for
keyword will call __iter__
(or the corresponding slot within the C implementation since the code involved is in the C interpreter) in order to loop over the list. for
关键字的实现将调用__iter__
(或 C 实现中的相应槽,因为所涉及的代码在 C 解释器中)以循环遍历列表。
In your second example you could have written在你的第二个例子中,你可以写
for elt in r:
print(elt)
which would have internally called __iter__
to implement the for loop.它会在内部调用__iter__
来实现 for 循环。
In general you tend to use for
rather than iter
and next
directly.一般来说,您倾向于直接使用for
而不是iter
和next
。 The cases where you use iter
and next
directly are when you're producing a callback function that will produce an iterator or when you're defining one iterator in terms of another.直接使用iter
和next
是当您生成一个将生成迭代器的回调函数时,或者当您根据另一个迭代器定义一个迭代器时。
In terms of when should you write your own __iter__
or return some object that does its own iteration, that all depends on what functionality you want. __iter__
何时应该编写自己的__iter__
或返回一些进行自己迭代的对象,这一切都取决于您想要什么功能。 For example, your first class is more powerful because two people can be iterating the list at the same time.例如,你的第一个类更强大,因为两个人可以同时迭代列表。 In your second class, because you store the index in the class itself, only one person can successfully use the iterator at a time.在您的第二个类中,由于您将索引存储在类本身中,因此一次只有一个人可以成功使用迭代器。 However, if you had complex enough behavior, the second approach where you define your own __iter__
might make sense.但是,如果您有足够复杂的行为,那么您定义自己的__iter__
的第二种方法可能是有意义的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.