1. 什么是生成器类?
在Python中,生成器是一种特殊的迭代器。它创建了一个迭代器,可以在每次调用时返回一个值,而且不会把所有的值都保存在内存中。相比较而言,列表等容器类型在创建时就已经将所有的元素都存储在内存中了,而对于大量数据的处理,则会消耗大量的内存。
生成器类就是继承了Python的yield技术,通过yield从函数中返回一个值,实现了一个迭代器而已。它有一个__next__()方法,每一次调用该方法都会自动执行相应的yield语句,并返回yield语句的值。这样一个生成器对象就可以被for循环、列表解析等使用。
2. 生成器类的基本使用
2.1 如何创建一个生成器类
下面是一个最简单的生成器类,它的作用是每次从1循环到10,返回1-10之间的数字:
class MyGenerator:
def __init__(self):
self.i = 1
def __iter__(self):
return self
def __next__(self):
if self.i <= 10:
self.i += 1
return self.i - 1
else:
raise StopIteration
在上面的代码中,我们定义了一个MyGenerator的类,它有__init__()方法、__iter__()方法和__next__()方法。该类的__iter__()方法返回一个迭代器对象,该对象有__next__()方法用于返回下一个值。
接下来我们就可以使用for循环调用MyGenerator,每次返回1-10中的数字:
my_gen = MyGenerator()
for i in my_gen:
print(i)
上述代码输出结果为:
1
2
3
4
5
6
7
8
9
10
2.2 使用yield语句创建生成器
在Python中,我们还可以使用yield语句创建一个生成器,如下所示:
def my_generator():
i = 1
while i <= 10:
yield i
i += 1
上面代码中,我们使用yield语句返回了一个值,并使用while循环来控制生成器的迭代次数。
我们可以通过for循环来调用上述生成器:
for i in my_generator():
print(i)
输出结果为:
1
2
3
4
5
6
7
8
9
10
使用yield语句创建生成器的好处是可以在每次迭代中暂停函数的执行,等到下一次迭代再从上次暂停的地方开始执行,这样既可以节省内存,又可以实现更加灵活的迭代模式。
3. 关于生成器的注意事项
3.1 生成器只能被迭代一次
生成器只能被迭代一次,如果需要重新迭代,需要重新创建一个生成器对象。如下所示:
my_gen = my_generator()
for i in my_gen:
print(i)
for i in my_gen:
print(i)
上面代码会输出1到10的数字,而第二个for循环处不会输出任何结果。
3.2 生成器可以接受外部传入的参数
在生成器类中,我们可以通过__init__()方法来接受外部传入的参数,并在生成器的迭代过程中使用这些参数。如下所示:
class MyGenerator:
def __init__(self, start=1, stop=10, step=1):
self.i = start - step
self.stop = stop
self.step = step
def __iter__(self):
return self
def __next__(self):
if self.i + self.step < self.stop:
self.i += self.step
return self.i
else:
raise StopIteration
上面代码中,我们在MyGenerator类的__init__()方法中定义了3个参数start、stop、step,用于控制生成器的开始、结束和步长。在__init__()方法中,我们保存了这些参数,并在后续的迭代过程中使用。
下面是使用上面的生成器调用的代码:
my_gen = MyGenerator(start=1, stop=10, step=2)
for i in my_gen:
print(i)
输出结果为:
1
3
5
7
9
可以看到,生成器每次迭代都返回指定步长的数字。
4. 总结
本文介绍了生成器类的概念、基本用法及注意事项。生成器类是Python中常用的迭代器类型之一,它可以大大提高程序的性能,并且可以节省大量的内存。我们可以通过继承Python的yield技术或使用yield语句来创建一个生成器类,并在其上完成迭代操作。同时在编写生成器类的时候,需要注意生成器只能被迭代一次,以及生成器可以接受外部传入的参数等问题。