作用:
__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)
相关连接: