【Python笔记-设计模式】迭代器模式

一、说明

迭代器模式是一种行为设计模式,让你能在不暴露集合底层表现形式(列表、栈和树等)的情况下遍历集合中所有的元素。

(一) 解决问题

遍历聚合对象中的元素,而不需要暴露该对象的内部表示

(二) 使用场景

  • 需要对聚合对象中元素进行遍历,并且不想暴露其内部结构
  • 减少程序中重复的遍历代码时
  • 能够遍历不同的甚至是无法预知的数据结构时

二、结构

  1. 迭代器(Iterator)接口声明了遍历集合所需的操作:获取下一个元素、获取当前位置和重新开始迭代等。
  2. 具体迭代器(ConcreteIterators)实现遍历集合的一种特定算法。迭代器对象必须跟踪自身遍历的进度。这使得多个迭代器可以相互独立地遍历同一集合。
  3. 集合(Collection)接口声明一个或多个方法来获取与集合兼容的迭代器。请注意,返回方法的类型必须被声明为迭代器接口,因此具体集合可以返回各种不同种类的迭代器。
  4. 具体集合(ConcreteCollections)会在客户端请求迭代器时返回一个特定的具体迭代器类实体。你可能会琢磨,剩下的集合代码在什么地方呢?不用担心,它也会在同一个类中。只是这些细节对于实际模式来说并不重要,所以我们将其省略了而已。
  5. 客户端(Client)通过集合和迭代器的接口与两者进行交互。这样一来客户端无需与具体类进行耦合,允许同一客户端代码使用各种不同的集合和迭代器。客户端通常不会自行创建迭代器,而是会从集合中获取。但在特定情况下,客户端可以直接创建一个迭代器(例如当客户端需要自定义特殊迭代器时)。

三、伪代码

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
__doc__ = """
迭代器模式

例:迭代树结构对象
"""

from collections.abc import Iterable, Iterator


class TreeNode:
    """树节点类"""

    def __init__(self, value):
        self.value = value
        self.children = []

    def add_child(self, child):
        self.children.append(child)

    def __str__(self, level=0):
        indent = " " * level
        result = f"{indent}{self.value}\n"
        for child in self.children:
            result += child.__str__(level + 4)
        return result


class Tree(Iterable):
    """聚合对象"""

    def __init__(self, root):
        self.root = root

    def __iter__(self) -> Iterator:
        return TreeIterator(self.root)


class TreeIterator(Iterator):
    """迭代器"""

    def __init__(self, node):
        self.stack = [node]

    def __next__(self):
        if not self.stack:
            raise StopIteration

        node = self.stack.pop()
        self.stack.extend(reversed(node.children))
        return node.value


if __name__ == "__main__":
    """
        A
        B
        D
        E
        C
        F
    """
    # 构建树形结构
    root = TreeNode("A")
    b = TreeNode("B")
    c = TreeNode("C")
    d = TreeNode("D")
    e = TreeNode("E")
    f = TreeNode("F")

    root.add_child(b)
    root.add_child(c)
    b.add_child(d)
    b.add_child(e)
    c.add_child(f)

    # 遍历树形结构
    tree = Tree(root)
    for value in tree:
        print(value)

四、优缺点

优点

  • 简化了聚合对象的接口:迭代器模式将遍历集合元素的责任分离出来,使得聚合对象和迭代器对象的职责更加清晰,聚合对象只需提供迭代器而无需关注遍历逻辑。
  • 隐藏了集合的内部结构:迭代器模式封装了集合的内部实现细节,使得客户端可以透明地访问集合元素,而不必关心集合的具体实现方式。

缺点

  • 不适合过于简单的集合:对于结构简单、元素数量少的集合,不如直接遍历集合来得简单直接。

【Python笔记】设计模式-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/419416.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

抖店怎么开店注册?新手需要准备什么?这几个步骤很关键!

我是电商珠珠 不少人瞄准了抖店这个短视频电商势头,想要在今年大干一场。关于抖店注册这方面,部分人还不太清楚,今天我就带大家一步步注册,看一遍就会了。 前期准备资料 前期新手的话,需要准备一张个体工营业执照&a…

C++/C百元买百鸡问题现在有100元要买100只鸡,一只公鸡5元,一只母鸡3元,三只小鸡一元,问今如何买?

具体代码如下 #include<stdio.h>int main() {int i, j, k;for (i 0; i < 20; i)for (j 0; j < 33; j) {k 100 - i - j;if (k % 3 0 && i * 5 j * 3 k / 3 100)printf("公鸡&#xff1a;%d&#xff0c;母鸡&#xff1a;%d&#xff0c;小鸡&…

p18 线性代数,行阶梯型矩阵

行阶梯型矩阵 行最简型矩阵

【VS Code】配置代码快捷提示

配置路径 进入如下界面&#xff0c;如果需要特定语言的配置&#xff0c;则选择相应的语言&#xff0c;这里演示为全局配置&#xff0c;没有创建过全局snippets配置的&#xff0c;使用New Global Snippets file 选项进行配置 然后在如下配置界面输入需要该配置的名称 配置编辑…

喜讯!持安科技CEO何艺获评安全419《2023年度十大优秀创业者》

近日&#xff0c;由网络安全产业资讯媒体安全419主办的《年度策划》2023年度十大优秀创业者正式出炉&#xff0c;零信任办公安全技术创新企业持安科技创始人兼CEO何艺&#xff0c;获评十大优秀创业者。 这是安全419第二届推出该项目的评选活动&#xff0c;安全419编辑老师在多年…

安装 Ubuntu 22.04.3 和 docker

文章目录 一、安装 Ubuntu 22.04.31. 简介2. 下载地址3. 系统安装4. 系统配置 二、安装 Docker1. 安装 docker2. 安装 docker compose3. 配置 docker 一、安装 Ubuntu 22.04.3 1. 简介 Ubuntu 22.04.3 是Linux操作系统的一个版本。LTS 版本支持周期到2032年。 系统要求双核 C…

【六袆 - React】Next.js:React 开发框架;Next.js开发框架的特点

Next.js&#xff1a;React 开发框架 Next.js的特点 1.直观的、基于页面的路由系统&#xff08;并支持动态路由&#xff09; Next.js 提供了基于文件系统的路由&#xff0c;意味着你可以通过创建页面文件来定义路由。 伪代码示例&#xff1a; // pages/index.js export defa…

挚达科技冲刺上市:乐视汽车曾是股东,多个投资者提前清仓提出

2月29日&#xff0c;上海挚达科技发展股份有限公司&#xff08;下称“挚达科技”&#xff09;递交招股书&#xff0c;准备在港交所主板上市&#xff0c;申万宏源香港为其独家保荐人。据此前媒体报道&#xff0c;挚达科技正在考虑赴港IPO&#xff0c;可能募集约10亿港元。 据官网…

three.js 向量叉乘cross

效果&#xff1a; 代码&#xff1a; <template><div><el-container><el-main><div class"box-card-left"><div id"threejs"></div><div></div></div></el-main></el-container>…

vulnhub-----Hackademic靶机

文章目录 1.C段扫描2.端口扫描3.服务扫描4.web分析5.sql注入6.目录扫描7.写马php反弹shell木马 8.反弹shell9.内核提权 1.C段扫描 kali:192.168.9.27 靶机&#xff1a;192.168.9.25 ┌──(root㉿kali)-[~] └─# arp-scan -l Interface: eth0,…

Vue ElementUI 修改消息提示框样式—messageBox 的大小

在窄屏模式下&#xff08;移动端或pda&#xff09;&#xff0c;提示框的宽度太宽&#xff0c;会出现显示不完全的问题。 应当如何修改 ElementUI 的样式呢&#xff1f; open() {this.$confirm(window.vm.$i18n.t("tips.conLogOut"),window.vm.$i18n.t("tips.tip…

数据库进阶——如何提升数据库的安全性,以MySQL和Redis加固为例

目录 引出数据库加固加固思路MySQLRedis Redis冲冲冲——缓存三兄弟&#xff1a;缓存击穿、穿透、雪崩缓存击穿缓存穿透缓存雪崩 总结 引出 数据库进阶——如何提升数据库的安全性&#xff0c;以MySQL和Redis加固为例 数据库加固 加固思路 账号配置 应按照用户分配账号&…

工厂模式:没你想像的那么难

工厂模式 工厂模式是一种创建型设计模式&#xff0c;它允许创建对象而无需指定将要创建的对象的具体类。它通过将对象的创建委托给一个单独的方法或类来完成&#xff0c;从而隐藏了对象的实例化逻辑。这样可以提高代码的灵活性&#xff0c;减少了代码中的重复和耦合。 在工厂…

css【详解】—— 圣杯布局 vs 双飞翼布局 (含手写清除浮动 clearfix)

两者功能效果相同&#xff0c;实现方式不同 效果预览 两侧宽度固定&#xff0c;中间宽度自适应&#xff08;三栏布局&#xff09;中间部分优先渲染允许三列中的任意一列成为最高列 圣杯布局 通过左右栏填充容器的左右 padding 实现&#xff0c;更多细节详见注释。 <!DOCTYP…

MySQL:数据库中有哪些锁

1、全局锁 加上全局锁后整个数据库就处于只读状态了&#xff0c;这时其他线程执行以下操作&#xff0c;都会被阻塞&#xff1a; 对数据的增删改操作&#xff0c;比如 insert、delete、update等语句&#xff1b;对表结构的更改操作&#xff0c;比如 alter table、drop table 等…

【AI+应用】怎么快速制作一个类chatGPT套壳网站

最近有人问我&#xff0c; 看了我之前写的一篇文章 [人工智能] AI浪潮下Sora对于普通人的机会 &#xff0c; 怎么做一个类chatGPT的套壳网站&#xff0c;是从0开始做么。 对于普通人来说&#xff0c;万事不懂先AI&#xff0c; AI找不到答案搜索google或百度。对于程序员来说…

电梯物联网之梯控相机方案-防止电瓶车进电梯

梯控现状 随着电梯产品在智能化建筑的日益普及,对于电梯的智能化管理 安全性需求 的要求越来越迫切。尤其今年来随着电瓶车的大量普及&#xff0c;发起多起楼道、轿厢电瓶车着火恶性事件&#xff0c; 造成了极大的社会 负面影响。控制电瓶车进入单元门&#xff0c;楼道以及电梯…

设计师面试作品集注意!避免以下6个陷阱!

作品集是设计师提交简历和面试的关键。因此&#xff0c;与其担心自己学历低&#xff0c;不懂谈判技巧&#xff0c;不如多关注作品集。看了很多设计师的简历和作品集&#xff0c;发现下面的坑经常被踩。为了避免这些坑&#xff0c;建议您选择即时设计来制作作品集&#xff0c; …

如何压缩pdf文件?几种高效压缩方法收好

如何压缩pdf文件&#xff1f;在日常工作和生活中&#xff0c;我们经常会在工作中使用pdf文件。然而&#xff0c;有时候过大的PDF文件会给我们的传输和存储带来不便。那么&#xff0c;如何有效地压缩PDF文件呢&#xff1f;本文将为你详细介绍几种简单实用的方法&#xff0c;让你…

MySQL 用了哪种默认隔离级别,实现原理是什么?

MySQL 的默认隔离级别是 RR - 可重复读&#xff0c;可以通过命令来查看 MySQL 中的默认隔离级别。 RR - 可重复读是基于多版本并发控制&#xff08;Multi-Version Concurrency Control&#xff0c;MVCC &#xff09;实现的。MVCC&#xff0c;在读取数据时通过一种类似快照的方…