python 迭代器和生成器

1.迭代器

1.迭代器的定义

1. 当类中定义了__iter__ 和 __next__两个方法。
2.__iter__方法需要返回对象本身,即:self
3.__next__方法,返回下一个数据,如果没有数据了,则需要抛出一个StopIteration的异常
官方文档:https://docs.python.org/3/library/stdtypes.html #iterator-types
# 创建迭代器类型
class IT(object):
    def __init__(self):
        self.counter = 0

    def __iter__(self):
        return self

    def __next__(self):
        self.counter += 1
        if self.counter == 3:
            raise StopIteration()
        return self.counter


# 根据类实例化创建一个迭代器对象
obj1 = IT()
# v1 = obj1.__next__()
# v2 = obj1.__next__()
# v3 = obj1.__next__()  # 抛出异常
v1 = next(obj1)
print(v1)

v2 = next(obj1)
print(v2)

v3 = next(obj1)
print(v3)

obj2 = IT()
for item in obj2:  # for 循环 首先会执行 迭代器对象 的 __iter__ 方法并获取返回值,一直去反复的执行 next(对象)
    print(item)

# 迭代器 对象支持 通过 next 取值,如果取值结束则自动抛出StopIteration
# for 循环内部在循环时,先执行__iter__方法,获取一个迭代器对象,然后不断执行的next 取值(有异常StopIteration则中止循环)

2.生成器

# 创建 生成器函数
def func():
    yield 1
    yield 2


# 创建生成器对象(内部使根据生成器类generator创建的对象),生成器类的内部也声明了,__iter__, __next__ 方法
obj1 = func()
v1 = next(obj1)
print(v1)

v2 = next(obj1)
print(v2)

v3 = next(obj1)
print(v3)

obj2 = func()

for item in obj2:
    print(item)

# 如果按照 迭代器的规则来看,其实生成器类 也是一种特殊的迭代器类

3.可迭代对象

#如果一个类中有__iter__方法且返回一个可迭代对象,则我们称这个类创建的对象为可迭代对象。

class FOO(object):
    def __iter__(self):
        return 迭代器对象(生成器对象)
obj = FOO()
# 可迭代对象使可以使用 for 来进行循环,在循环的内部其实是先执行 __iter__方法,获取其迭代器对象,然后再在内部执行这个迭代器对象的next功能,逐步取值。

for item  in obj:
    pass
class IT(object):
    def __inti__(self):
        self.counter = 0
     
    def __iter__(self):
        return self
    
    def __next__(self):
        self.counter += 1
        if self.counter == 3:
            raise StopIteration()
         return self.counter
class Foo(object):
    def __iter__(self):
        return IT()
    
obj = FOO() # 可迭代对象

for item in obj:
    print(item)
# 基于可迭代对象 & 迭代器 实现:自定义 range
class IterRange(object):
    def __init__(self, num):
        self.num = num
        self.counter = -1

    def __iter__(self):
        return self

    def __next__(self):
        self.counter += 1

        if self.counter == self.num:
            raise StopIteration()
        return self.counter


class Xrange(object):
    def __init__(self, max_num):
        self.max_num = max_num

    def __iter__(self):
        return IterRange(self.max_num)

obj = Xrange(100)

for item in obj:
    print(item)



class FOO(object):
    def __iter__(self):
        yield 1
        yield 2
obj = FOO()
for item in obj:
    print(item)
# 基于可迭代对象& 生成器,实现:自定义 range
class Xrange(object):
    def __init__(self,max_num):
    	self.max_num = max_num
    def __iter__(self):
        counter = 0
        while counter < self.max_num:
            yield counter
            counter += 1
        
obj = Xrange(100)
for item in obj:
    print(item)
    
    

4.常见的数据类型

v1 = list([11,22,33,44])

v1 是一个可迭代对象,因为在列表中声明了一个__iter__方法 并且返回一个可迭代对象

>>> v1 = list([11,22,33,44])
>>> dir(v1)
['__add__', '__class__', '__class_getitem__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
>>> v2 = v1.__iter__()
>>> dir(v2)
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__length_hint__', '__lt__', '__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__']
>>> v2.__next__()
11
>>> v2.__next__()
22
>>> v2.__next__()
33
>>> v2.__next__()
44
>>> v2.__next__()
Traceback (most recent call last):
  File "<pyshell#9>", line 1, in <module>
    v2.__next__()
StopIteration
>>> 

5.如何判断一个对象是不是可迭代对象或者 迭代器

from collections.abc import Iterator, Iterable
v1 = [11, 22, 33]
print(isinstance(v1, Iterator))  # false  ,判断是否是迭代器,判断依据是 __iter__ 和 __next__
v2 = v1.__iter__()
print(isinstance(v2, Iterator))  # True

print(isinstance(v1, Iterable))  # True, 判断依据是是否有 __iter__ 且返回迭代器对象

print(isinstance(v2, Iterable))  # True  判断依据是是否有 __iter__ 且返回迭代器对象.

posted @ 2025-05-19 18:46  Ref-brief  阅读(26)  评论(5)    收藏  举报