python __iter__,__next__使用

作用:

__iter__: 把一个对象改为 可迭代对象

__next__ : 可迭代对象中 获取下一个数据,注意方法中 为了 不进行无限迭代, 需要有 raise StopIteration   在符合条件时停止迭代;

用途:

  • 在想定义自己的迭代方式时 可以用此2个方法;
  • 使用时,可以配合for循环;
  • 可以在 设计模式的 迭代模式中使用

如下 示例表示迭代 dict中的值 依次遍历

示例代码:

# -*- coding: utf-8 -*-
"""
(C) Guangcai Ren <rgc@bvrft.com>
All rights reserved
create time '2020/12/30 19:20'

Usage:
迭代器模式使用示例
实现 二叉树的 广度遍历和深度遍历
"""
from copy import deepcopy
from queue import Queue


class Forefathers:
    """
    组件 或 抽象构件 角色 主要 声明 公共方法
    """
    queue = Queue()

    def __init__(self, name, age, gender):
        self.name = name
        self.age = age
        self.gender = gender

    def __str__(self):
        """"""
        return self.name

    def add(self, someone):
        pass

    def remove(self, someone):
        pass

    def __iter__(self):
        """
        此方法 将对象转为可迭代对象
        此方法 返回值必须是个可迭代对象;
        :return:
        """
        # 可迭代对象使用 Introduce的实例化;
        # 也就是说 后续的 迭代获取下一个 数据 其实用的就是 Introduce实例化对象的 __next__方法
        obj = Introduce(self)
        obj.dfs_lf_list()
        return obj

    def dfs_lf(self):
        obj = Introduce(self)
        obj.dfs_lf_list()
        return obj

    def dfs_rf(self):
        obj = Introduce(self)
        obj.dfs_rf_list()
        return obj


class Parents(Forefathers):
    """
    容器 或 组合 角色
    父母 类 可以有后代
    """

    def __init__(self, name, age, gender):
        """

        :param name:
        :param age:
        :param gender:
        """
        super(Parents, self).__init__(name, age, gender)
        self.children = []

    def add(self, *someone):
        """
        新增 子孙
        :param someone:
        :return:
        """
        self.children += someone

    def remove(self, someone):
        """
        移出 祖籍
        :param someone:
        :return:
        """
        self.children.remove(someone)


class Child(Forefathers):
    """
    叶节点 角色
    孩童 类 没有后代
    """

    def __init__(self, name, age, gender):
        """

        :param name:
        :param age:
        :param gender:
        """
        super(Child, self).__init__(name, age, gender)


class Introduce:
    def __init__(self, been_iter):
        self.been_iter = been_iter
        self._p = 0
        self.name_list = []
        # self.dfs_lf_list(been_iter)
        # self.dfs_rf_list(been_iter)

    def dfs_lf_list(self, been_iter=None):
        """
        先将 被迭代的 嵌套层级数据 按照一定规则剥离层级关系 抽取到一个list中;目的为了在__next__方法中方便遍历
        如 原来是 [[1,2],3,[4,[5,[6,[7]]]]] 转为:[1,2,3,4,5,6,7]
        此处遍历方法如下:
        深度优先遍历
        前序遍历
        :return:
        """
        if not been_iter:
            been_iter = self.been_iter
        self.name_list.append(been_iter.name)
        if hasattr(been_iter, 'children'):
            for item in been_iter.children:
                self.dfs_lf_list(item)

    def dfs_rf_list(self, been_iter=None):
        """
        先将 被迭代的 嵌套层级数据 按照一定规则剥离层级关系 抽取到一个list中;目的为了在__next__方法中方便遍历
        如 原来是 [[1,2],3,[4,[5,[6,[7]]]]] 转为:[1,2,3,4,5,6,7]
        此处遍历方法如下:
        深度优先遍历
        后序遍历
        :return:
        """
        if not been_iter:
            been_iter = self.been_iter
        self.name_list.append(been_iter.name)
        if hasattr(been_iter, 'children'):
            children = deepcopy(been_iter.children)
            children.reverse()
            for item in children:
                self.dfs_rf_list(item)

    def __next__(self):
        """
        获取下一个数据
        :return:
        """
        try:
            val = self.name_list[self._p]
            self._p += 1
        except IndexError:
            # 停止迭代的方法
            raise StopIteration
        return val

    def __iter__(self):
        """
        此方法 将对象转为可迭代对象
        :return:
        """
        return self


if __name__ == '__main__':
    """
    """
    root = Parents('第一代祖宗', 1800, 'man')

    sec_man = Parents('第二代男祖宗', 1840, 'man')
    sec_man1 = Parents('第二代男1祖宗', 1840, 'man')
    sec_woman = Parents('第二代女祖宗', 1840, 'woman')
    root.add(sec_man, sec_woman, sec_man1)

    last_one = Child('最早灭绝一代', 1860, 'man')
    sec_man.add(last_one)

    third_woman = Parents('第三代女祖宗', 1860, 'woman')
    sec_woman.add(third_woman)
    third_man = Parents('第三代男祖宗', 1860, 'man')
    sec_woman.add(third_man)

    four_man = Parents('第四代男祖宗', 1890, 'man')
    third_woman.add(four_man)

    last_one = Child('最后一代', 1890, 'man')
    third_woman.add(last_one)

    print('开始执行 默认的迭代方式(前序遍历)', '*' * 10)
    for item in root.__iter__():
        print(item)
    for item in root:
        print(item)

    print('开始执行 前序遍历', '*' * 10)
    for item in root.dfs_lf():
        print(item)

    print('开始执行 后序遍历', '*' * 10)
    for item in root.dfs_rf():
        print(item)
# -*- coding: utf-8 -*-
"""
(C) Guangcai Ren <rgc@bvrft.com>
All rights reserved
create time '2020/12/30 13:18'

Usage:

"""


class IterDictVal:
    """
    迭代字典的值
    """

    def __init__(self, k_v_map):
        """
        初始化
        :param k_v_map:
        """
        self.v_list = list(k_v_map.values())
        self.v_list.reverse()

    def __iter__(self):
        """
        将对象变为可迭代对象
        :return:
        """
        return self

    def __next__(self):
        """
        获取下一个数据
        :return:
        """
        if self.v_list:
            return self.v_list.pop()
        else:
            raise StopIteration


if __name__ == '__main__':
    # for ... in  xxx   首先 xxx必须是一个可迭代对象(有__iter__方法),其次 必须要有next方法 供for循环一直查找下一个;
    for item in IterDictVal({'a': 1, 'b': 2, 'c': 3}):
        print(item)
    for item in IterDictVal({'a': 1, 'b': 2, 'c': 3}).__iter__():  # 被迭代对象默认调用的就是 __iter__方法
        print(item)

相关连接:

https://blog.csdn.net/abcx3261/article/details/88966547?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1.control

https://blog.csdn.net/will130/article/details/50920501?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromBaidu-1.control&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromBaidu-1.control

https://blog.csdn.net/liweibin1994/article/details/77374854

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值