Python基础26-面向对象(系统内置方法6-遍历操作)

Python基础-面向对象(方法)

6 遍历操作

* 怎样让我们自己创建的对象可以使用for in 进行遍历?
    + 实现__getitem__方法
        优先级低
        - 每次for in 获取数据时, 都会调用这个方法
    或者

    + 实现__iter__方法
        优先级高
        - 这个方法, 必须返回一个"迭代器"; 
          "迭代器"即, 具备"__iter__"和"__next__"方法
          当for in 遍历这个对象时, 会调用这个__iter__方法返回的迭代器对象的__next__方法

* 怎样让我们自己创建的对象可以使用 next() 函数进行访问?
    实现__next__方法

补充
    1. __iter__方法可以恢复迭代器的初始化值, 复用迭代器
    2. "可迭代" 与 "迭代器"必须实现的方法
    3. iter方法的使用
  • 实现__getitem__方法
class Person:
    def __init__(self):
        self.result = 1

    def __getitem__(self, item):
        self.result += 1
        if self.result >= 6:
            raise StopIteration("停止遍历") #通过抛出异常结束遍历,否则会死循环

        return self.result

p = Person()

for i in p:
    print(i)
  • 实现__iter__方法
    __iter____getitem__方法同时实现,前者优先级高
# 返回迭代器 list
class Person:
    def __init__(self):
        self.result = 1

    def __iter__(self):
        print("iter")
        self.result = 1
        return iter([1, 2, 3, 4, 5]) #返回迭代器时,会调用迭代器内部的__next__方法

p = Person()

for i in p:
    print(i)
# 不返回迭代器时,则会调用实例内部的 __next__ 方法
# 所以 iter 函数一般与 next 函数组合使用
class Person:
    def __init__(self):
        self.result = 1

    def __iter__(self):
        print("iter")
        return self

    def __next__(self):
        self.result += 1
        if self.result >= 6:
            raise StopIteration("停止遍历")
        return self.result

p = Person()

for i in p:
    print(i)
  • 验证迭代器所具备的条件
    实现了__next__方法不一定就是迭代器,迭代器必须要同时实现__iter____next__方法才行
import collections

class Person:
    def __iter__(self):
        pass

    def __next__(self):
         pass


p = Person()
print(isinstance(p, collections.Iterator)) # 是迭代器
print(isinstance(p, collections.Iterable)) # 也是可迭代对象,但是,可迭代对象只需要实现__iter__方法即可

对象 是 Iterable 一定能使用 for in
能使用for in 的对象不一定是 Iterable,因为只实现__getitem__的也是可以执行 for in

  • 通过__iter__初始化条件,让自定义迭代器重复使用
class Person:
    def __init__(self):
        self.age = 1


    def __iter__(self):
        self.age = 1
        return self

    def __next__(self):
        self.age += 1
        if self.age >= 6:
            raise StopIteration("stop")

        return self.age


p = Person()

for i in p:
    print(i)

print("-" * 20)

for i in p:
    print(i)

>>>> 打印结果
2
3
4
5
--------------------
2
3
4
5
  • iter()函数的使用
  1. 将对象转化成迭代器
l = [1, 2, 3]
lt = iter(l)
print(lt)

>>> 打印结果

  1. 将实现getitem方法的自定义对象 转化成迭代器
class Person:
    def __init__(self):
        self.age = 1

    def __getitem__(self, item):
        self.age += 1
        if self.age >= 6:
            raise StopIteration("stop")
        return self.age

p = Person()
print(p)
pt = iter(p)
print(pt)

print("-" * 20)

for i in pt:
    print(i)

>>> 打印结果
<__main__.Person object at 0x107be8208>

--------------------
2
3
4
5
  1. 将自定义的迭代器对象(同时实现了iternext,缺少一个都会报错) 转成 迭代器
class Person:
    def __init__(self):
        self.age = 1

    def __iter__(self):
        self.age = 1
        return self

    def __next__(self):
        self.age += 1
        if self.age >= 6:
            raise StopIteration("stop")
        return self.age

p = Person()

pt = iter(p) # 即使p 实例已经是迭代器,再通过 iter 转换是不会变的,即 pt = p
print(pt)

print(pt is p)

print("-" * 20)

for i in pt:
    print(i)

>>> 打印结果
<__main__.Person object at 0x105462208>
True
--------------------
2
3
4
5
  1. iter(x, y)第二个参数使用


# 当 x 为 callable 时 + __getitem__
class Person:
    def __init__(self):
        self.age = 1

    def __getitem__(self, item):
        self.age += 1
        if self.age >= 6:
            raise StopIteration("stop")
        return self.age

p = Person()
pt = iter(p, 4)

for i in pt:
    print(i)

>>> 打印结果
Traceback (most recent call last):
  File "xxx", line xx, in 
    pt = iter(p, 4)
TypeError: iter(v, w): v must be callable

# 通过 iter(callable, sentinel)方式使用

class Person:
    def __init__(self):
        self.age = 1

    def __call__(self, *args, **kwargs):
        self.age += 1
        if self.age >= 6:
            raise StopIteration("stop")
        return self.age

p = Person()
pt = iter(p, 4)

for i in pt:
    print(i)

>>> 打印结果
2
3
# 也可以不实现 __call__
class Person:
    def __init__(self):
        self.age = 1

    def __iter__(self):
        self.age = 1
        return self

    def __next__(self):
        self.age += 1
        if self.age >= 6:
            raise StopIteration("stop")
        return self.age

p = Person()
pt = iter(p.__next__, 4)

for i in pt:
    print(i)

>>> 打印结果
2
3

你可能感兴趣的:(Python基础26-面向对象(系统内置方法6-遍历操作))