🦖
Wii
  • 原码补码反码
  • Archive
    • Job
      • Learn
      • 算法
      • Company
        • HundunDaxue
      • Company
      • 基础
        • 原码补码反码
      • 项目经验
      • require
    • Hobbies
      • Physics
        • 上帝粒子
        • 概述
        • 时间
      • Movie
        • MovieList
      • Psychology
        • Psychology
        • Chenli
          • ChenliLivingRoom
      • Philosophy
        • Philosophy
        • Conceptions
        • 导言
      • Travel
        • City
          • 昆明
          • 沈阳
        • articles-check-list
      • Sports
        • Swimming
        • Skiing
      • Earth
        • Ocean
          • Biology
      • Read
        • BookList
        • 道德经
        • BookToRead
      • Music
        • sort
      • PickUp
        • SoldiersSortie
    • Care
      • Illness
        • cold
        • 腹泻
        • acne
        • EmotionalControl
        • 咽炎
        • Anemia
      • Foods
        • 破壁机
          • 食谱
      • I
      • WishList
      • WithL
        • MF
          • LY
    • Wfw
      • QA
    • Mac
      • Brew
        • 软件安装目录
      • Usage
        • RunScriptAsRootOnBoot
        • Mac-Config
      • 制作启动U盘
      • Software
        • IntelliJIDEALicenseServer
          • run-license-server
    • PlantUML
      • plantuml
    • Windows
      • Windows常用命令
      • PowerShell
        • powershell 命令
      • Cmder
      • MTP服务驱动无法安装
    • English
      • 英语阅读2016-07-29
      • 英语阅读2016-08-11
    • Tools
      • Plantuml
        • Setup
      • Eclipse
        • Eclipse
        • Eclipse常见问题
      • CommonHotkey
      • Jetbrain
        • JetbrainIDEs
      • VSCode
      • SublimeText
        • 格式化代码
    • I
      • WHATIAM
    • Device
      • Netgear
        • Astrill
      • RPi
        • Hardware
    • AwesomeSoftware
    • RESTful
    • Course
      • 自然辩证法
        • 我国在生态文明建设中存在的困境及解决对策
        • 工程师应该具有的基本道德素养
        • 科学文化与人文文化的关系
      • 英语写作
        • Description
      • 分布式系统
        • 分布式系统概论
      • 英语口语
        • 辩论赛
    • CloudLib
      • 推荐0.1
    • Project
      • README
        • emq
          • Emq架构
        • 启动
        • Hikvision
          • TimeSetting
    • Efficient
    • Neu
      • IpCamera
        • live
        • ffmpeg
    • Matlab
      • Matlab 2016b 破解
    • SchoolWork
      • 学术道德与学术规范
    • git-push
  • Coding
    • Design Pattern
      • 设计模式笔记_四_工厂模式
      • 设计模式笔记_六_命令模式
      • 设计模式笔记_三_装饰者模式
      • 设计模式入门
      • 设计模式笔记_八_模板方法模式
      • 设计模式笔记_一_策略模式
      • 设计模式笔记_五_单件模式
      • 设计模式笔记_七_适配器模式与外观模式
      • 设计模式笔记_二_观察者模式
      • 设计模式笔记_十_状态模式
      • 设计模式笔记_九_迭代器与组合模式
    • C++
      • Notes
        • Practice
          • Logger
        • Thread
          • PosixThreadPrograming
          • ThreadNote
        • Features
          • FuturePromise
          • Lambda
        • STL
          • STLPractice
          • 迭代器
          • UnorderedMapSet
          • Containor
          • STL
          • Vector
        • CMake
          • Startup
          • CMakeExample
          • CMake
          • CMakeUsage
          • CMakeKnowledge
        • Mutex
        • Gdb
          • Gdb
        • LanguageNotes
          • Pointer
          • String
          • Functions
          • 友元
          • IO
          • OOP
          • Exceptions
          • Basic
          • 初始化
          • Random
          • 模板函数
        • Glog
          • glog
        • Thrift
          • Thrift
        • Valgrind
          • valgrind
        • 动态库 & 静态库
        • BookNotes
          • AboutC++
        • LRvalues
      • map
      • protobuf
      • Build
      • Seastar
        • Notes
          • std::move
          • Introduce
          • Install
            • BuildAndInstall
          • Steps
          • cmd
      • Tricks
      • Map
      • CommonOperation
      • FreqAlgorithm
    • Tools
      • Git
        • GitExamples
        • GitUsage
        • GitKnowledge
        • GitIgnoreExample
        • DeleteBigFileFromHistory
      • Vim
        • VimTips
        • 安装
        • Vim-Usage
        • Plugins
        • Vim-Config
      • SVN
        • svn服务器搭建
        • svn
    • Scala
      • Notes
        • Scala-模式匹配
        • Scala: 隐式
        • Scala-符号语法
        • Scala-函数
        • Scala面向对象编程
        • Scala 函数式编程
        • Scala:zipWithIndex
        • Future
        • Scala-语法
        • Scala-基础
      • DateTime
      • 规范
    • Python
      • Notes
        • BookNotes
          • 生成器
          • 垃圾回收机制
          • 数据结构
          • 数据类型
          • RegularExpression
          • 迭代器
          • NetworkProgramming
          • 函数式编程
          • 上下文管理器
          • PythonDataModel
          • 运算符
          • 魔术方法
          • 面向对象
          • 装饰器
          • 模块
          • MultithreadProgramming
          • 异常
          • 函数
        • Modules
          • stack
          • Datetime
          • shutil:文件操作
          • logging
          • urllib
          • Re
          • 容器数据类型
          • TypeError
          • str
          • queue
          • urllib-and-requests
          • Exception
          • path
          • os
        • Others
          • PythonSerialization
          • Python函数的docstring
          • PIL
          • type-cast
          • operations
          • Python-类
          • 组及命名组匹配
          • Package
          • jieba分词
          • logging模块
          • Python
          • print
        • Examples
          • 文件读取写入
          • 命名
          • 递归更改文件为windows合法名称
          • 定制命令行运行方式
          • Python处理Excel文件(xlsx文件格式)
          • 读取ini配置文件
          • tor代理
          • 添加父目录到Path
        • CommonTips
        • CodingStandards
          • python注释
          • PEP-8
      • Django
        • DjangoDocs
          • making queries
          • 设置media路径
          • models
          • manage.py使用
          • template
          • view
          • forms
          • setting.py 文件配置说明
          • nginx-deploy
          • 使用pymysql
          • 自定义tags和filters
          • admin-interface
        • DjangoRestFramework
          • Customer Permissions
          • Serializers
          • FileField绝对路径问题
          • DjangoRestFrameworkNotes
          • ViewSet
        • DjangoNotes
          • Model对象转化为Dict
          • QuerySet
      • Scrapy
        • Scrapy
        • Spider
        • Scrapy安装出错
        • Selector
        • Scrapy模拟登陆
      • Job
        • 字典
      • Pandas
        • pandas
        • PandasExamples
      • VirtualEnv
        • virtualenv
      • Numpy
        • NumpyUsage
        • numpy
      • Matplotlib
        • MatplotlibNotes
        • MatplotlibUsage
      • Database
        • 获取表字段
      • Pip
        • 更改源
      • Scipy
        • scipy
    • Web
      • 插件
        • bootstrap-table
          • bootstrap-table
        • bootstrap
          • 模态框
        • requirejs
          • requirejs
        • toastr
          • toastor
      • Koa
        • Notes
          • KoaNotes
      • SCSS
        • 常用标签
        • Watch
      • Vue
        • Notes
          • 路由
          • 参考
          • 组件
          • Plugins
          • Vuex
          • StartUp
      • 样式
      • CSS
        • CSS
      • 排版
      • Notes
        • 跨域访问
      • Hexo
        • HexoUsage
      • Nodejs
        • Koa
          • jest
          • ParamValidate
        • 仓库镜像
      • Express
        • Express
        • Jade
          • Jade
      • Canvas
        • Canvas
    • Basic
      • Data Structure
        • Heap
          • Heap
        • Tree
          • Tree
        • Benchmark
          • map
      • Boolean
      • MultithreadProgramming
      • Software Engineering
        • UML
          • UML
      • OOP
      • 介绍
    • Antlr
      • Example
      • Grammar
      • Antlr
    • Java
      • Library
        • MyBatis
          • generator
            • mybatis配置详解
          • mybatis-获取自增ID
          • mybatis
          • problems
        • log4j
          • Usage
      • Maven
        • MavenUsage
        • Maven
        • MavenProject
        • 项目RUL路径问题
        • MavenPom
        • Settings
        • PomCommon
        • PomExample
      • Notes
        • Features
          • Reflect
          • Java函数式编程
          • toMap
          • Closeable & AutoCloseable & Flushable
          • Annotations
        • Common
        • ThinkingInJava
          • 控制执行流程
          • 接口
          • 复用类
          • 内部类
          • 操作符
          • 访问权限控制
          • 一切都是对象
          • 多态
          • 初始化与清理
          • 对象导论
        • SwordToOffer
        • Network
        • Thread
          • ThreadPool
        • Basic Library
        • Collections
          • List Interface
        • CommandLine
        • Project Common
        • JavaLang
      • JVM
        • Monitor
          • Jmap
          • mat
          • Jstat
          • Monitor
        • Notes
          • JVM
        • GC
          • GC
          • Shenandoah
            • Shenandoah
        • JVM
    • Algorithm
      • Code
        • LeetCode
          • Python
            • 0000-0050
              • 0005
              • 0030
        • SwordToOffer
          • SwordToOffer
      • AlgorithmSummary
      • Classics
        • string
          • KMP
        • Other
          • FullPermutation
        • 链表
        • Sort
          • Sort
      • Other
        • README
      • Notes
        • Math
          • 两点计算直线方程
    • Go
      • Notes
        • Go Project Layout
        • Install
        • Startup
      • Basic
        • Startup
        • Types
    • JavaScript
      • MasonryLayouts
      • jquery
      • Notes
        • Promise
      • js
    • Android
      • SDK
        • 打开SDK Manager
    • C#
      • WebBrowser
      • c#图片
      • 跨线程访问控件
    • Knowledge
      • 函数式编程
      • 设计框架
    • Rules
      • Rules
    • React
      • ReactNative
        • React Native Navigation
        • 打包Apk
        • ReactNative
      • React
        • README
    • RegExp
      • 正则表达式
    • WeChatApp
      • 登陆
    • Node
      • Notes
        • StartUp
  • Computer Science
    • ICS Security
      • 工控网络
      • 工业控制系统
      • HoneyPot
        • 蜜罐软件
          • Honeyd
      • 工业以太网
      • CNVD
        • 环境及依赖
      • 现有蜜罐系统及工具
      • 工控系统安全措施
      • 蜜网
      • 蜜罐
      • 工控安全相关概念
    • Data Analysis
      • Data Mining
        • Notes
          • Data_Preprocessing
          • 数据预处理
          • 认识数据
          • Mining_Modeling
          • 数据探索
          • Python_Data_Mining_Functions
          • Python数据分析平台搭建
          • Reference_Books
          • 数据分析与挖掘基础
        • Jupyter
          • show
            • mean
      • Hadoop
        • Hadoop权威指南:数据完整性
        • Hadoop权威指南: I/O操作序 - 列化
        • Hadoop权威指南-从Hadoop URL读取数据
        • Hadoop权威指南:FSDataInputStream对象
        • HDFS常用命令
        • Hadoop权威指南:HDFS-数据流
        • Hadoop权威指南:通过distcp并行复制
        • Hadoop权威指南:压缩
        • Hadoop权威指南:HDFS-Hadoop存档
        • 解决使用Idea/Eclipse编写Hadoop程序包依赖问题
        • HDFS
        • Hadoop-命令
        • 简单javaHadoop应用程序从打包到提交运行
        • Hadoop权威指南:HDFS-写入数据
        • Hadoop权威指南:HDFS-目录,查询文件系统,删除文件
        • HadoopInputFormat-OutputFormart
        • Hadoop-HDFS命令行接口
        • Hadoop权威指南-MapReduce应用开发
        • Linux下使用javac编译Hadoop程序
        • Hadoop权威指南:通过FileSystem API读取数据
        • Hadoop专有数据类型
      • Spark
        • Spark计算模型
        • Spark-入门二
        • 安装Hadoop及Spark(Ubuntu 16.04)
        • Spark:核心概念简介
        • Spark:控制日志输入
        • Spark - RDD编程
        • Spark工作机制
        • Spark-一个独立应用
        • Spark
        • Spark:使用Spark Shell的两个示例
    • Linux
      • Notes
        • BuildInCommand
          • ls
          • ip
          • ftp
          • 目录栈操作
          • scp
          • expect
            • expect示例
            • expect手册
            • expect笔记
          • ps
          • vsftpd
          • wget
          • 压缩程序
            • zip_unzip
            • tar
            • p7zip
          • 部署web服务
          • avidemux
          • cat
          • Awk
          • find
          • pssh使用
          • grep
          • sed
          • 路径
          • 通用命令
          • 安装JDK
          • 进程管理
          • network
          • rsync
          • cron
          • 示例
          • 用户管理
          • supervisor
        • Common
        • TestFileProcess
          • 替换文件内容
        • Commonds
        • Permissions
      • Ubuntu
        • Ubuntu 服务器配置部署
        • Ubuntu笔记
        • Ubuntu网络配置
        • Ubuntu 16.04 几个国内源
      • Script
        • ShellProgramming
        • ShellExamples
        • ShellCommands
      • CentOS
        • Centos笔记
        • 源
        • CentOS-Network-Config
        • CentOS-Security
      • Squid
        • BuildByDocker
        • Squid
      • Problem
        • 常见错误
      • Linux
        • Linux-c-cpp
        • Linux
        • Linux-NetworkProgramming
      • Codes
        • cron-test-01
      • Software
        • Shortcut key
        • Anaconda
      • Make
        • tricks
      • Deepin
        • 安装docker
      • SRE
        • CommonCommand
    • Cloud Computing
      • OpenStack
        • Fuel离线安装OpenStack
        • 验证网络
        • OpenStackNotes
    • Network
      • TCP/IP
      • 套接字
      • OSI模型
    • Data mining
      • StartUp
    • Machine Learning
      • Notes
        • 决策树学习-周志华
        • 神经网络-周志华
        • 概念学习和一般到特殊序
        • MachineLearningProblems
        • Math
          • 概率论与数理统计
          • 数学概念
          • KKT条件
          • 最优化问题
          • 优化算法
          • 最小二乘
        • 模型评估与选择
        • 引言
        • 过拟合处理
        • StatisticalLearningMethod
          • 统计学习方法概论
          • 感知机
        • 评估假设
        • Code
          • FeatureEngineering
            • Iris
        • 概念
        • SVM
        • FeatureEngineering
        • 神经网络
        • 决策树学习
        • MachineLearningKnowledge
        • 线性模型
        • 术语概念
        • 拉格朗日乘子法
      • route
      • Jupyter
        • JupyterUsage
      • Anaconda
        • AnacondaUsage
      • Coursera
        • Week01
      • ScikitLearn
        • FitTransform
        • Preprocessing
      • Octave
        • Octave
    • Search
      • Lucene
        • Api
        • Concepts
    • Virtualization Tech
      • Docker
        • dockerNetwork
        • Ubuntu
        • DockerUsage
        • Mac OS
    • Database
      • MySQL
        • Mysql Cluster
        • mysql-cluster
        • mysql
      • 部署phpmyadmin
      • SQL
      • SQL
        • SQLStatement
    • Concepts
      • Other
      • Mohout
      • LDA
    • Distributed System
      • Concepts
        • TODO
        • TODO
    • Recommend System
      • DataPipline
        • DataBus
        • 系统
    • OS
      • OS-Code
      • Notes
        • Introduce
        • ProcessManagement
        • Kernel
    • Deep Learning
      • Code
        • README
      • Notes
        • Conceptions
        • 神经网络
        • LeNet5
        • CNN
      • Tensorflow
        • Notes
          • Tensorflow
          • tensorflow开始
        • Anaconda
    • Media
      • FFmpeg
        • LiveStream
          • run
    • Spider
      • Selenium
        • Selenium
    • IoT
      • emq
        • Authentication
    • Big Data
      • Hadoop
        • MR 作业
  • Architecture
    • Storage
      • Mongodb
        • Mongodb
        • Failed to unlink socket file
      • Pegasus
        • Pegasus
        • ShellTools
      • Rocksdb
        • RocksJava
        • RocksDB
        • 本地缓存
      • Redis
        • Install
        • RedisUsage
      • 基本要素
      • HBase
        • HBase
    • MQ
      • Kafka
        • VersionCompare
        • Deploy
        • cppkafka
        • CommandLineTools
        • OffsetManage
        • Attentions
        • Notes
        • QA
    • Framework
      • Java
        • Dubbo
          • Annotation
          • 简介
        • Spring
          • SpringTest
          • 常见错误
          • TransactionRollback
          • FileUpload
          • SpringMVCNote
          • IoC
          • Start
          • Notes
            • Config
          • Spring
          • springmvc
          • Modules
        • Rose
          • Get request body
        • Netty
          • Netty
        • SpringBoot
          • SpringBoot
      • Esper
        • Documents
          • Keyed Segmented Context
          • 01 - Getting Started
          • 02 - Event Representations
          • 03 - Processing Modal
      • Swagger
        • Swagger
    • RPC
      • Thrift
        • Notes
          • Set fields
          • ThriftTyps
        • BuildFromSource
        • ThriftUsage
        • Install
      • ProtocolBuffer
        • 减少内存拷贝
        • UsageExample
        • Arena
        • ProtocolBuffer
    • Distribution
      • CAP
    • Streaming
      • Spark
        • Init
      • MapReduce
      • Spark
    • Nginx
      • Nginx knowledge
      • nginx-configurtion
      • 403
      • nginx解析php文件时502
    • Governance
      • Consul
      • Zookeeper
        • Zookeeper
      • MicroServiceArchitecture
      • 依赖
    • Conceptions
      • CloudNative
    • Kibana
      • Query
    • Performance Optimizaition
      • Notes
        • Conceptions
        • CPUAffinity
  • Math
    • Probability Theory
      • 一些概率分布
    • Statistics
      • 统计量与估计量
    • Other
      • 排列组合
  • Tools
    • Markdown
      • syntax
    • Jetbrains
      • Jetbrains
    • Zsh
      • Install
  • TODO
由 GitBook 提供支持
在本页
  • 第三章 生成器
  • 3.1 理解生成器
  • 3.2 生成器语法
  • 3.3 与生成器之间的交互
  • 3.4 迭代器对象与迭代器
  • 3.5 标准库中的生成器
  • 3.6 生成器单例模式
  • 3.7 生成器内部的生成器
  • 第一种调用方式
  • 第二种调用方式, 使用 itertools.chain
  • 第三种调用方式, 使用 yield from 语句

这有帮助吗?

  1. Coding
  2. Python
  3. Notes
  4. BookNotes

生成器

[TOC]

第三章 生成器

3.1 理解生成器

  • 生成器处理值序列时允许序列中的每一个值只在需要时才计算

  • 使用生成器可以节省大量内存

  • 生成器能够处理一些无法由列表准确表示的序列形式

  • 生成器是一个函数, 按照顺序返回一个或多个值

3.2 生成器语法

  • 通常, 生成器在函数内部包含一个或多个yield语句

  • 像return语句一样, yield语句命令函数返回一个值给调用者, 但不会终止函数的执行, 执行会暂停直到调用代码重新恢复生成器, 在停止的地方再次开始执行

  • 简单示例

    # 代码
    def fibonacci():
        yield 1
        yield 1
        yield 2
        yield 3
        yield 5
        yield 8
        pass
    
    for i in fibonacci():
        print(i)
        pass
    # 输出
    D:\Software\Installed\Python\Python36\python.exe D:/workspace/Pycharm/PurePythonProject/Test01.py
    1
    1
    2
    3
    5
    8
    
    Process finished with exit code 0

3.2.1 next函数

  • Python内置了next函数, 能够让生成器请求它的下一个值

  • 简单示例

    # 代码
    def fibonacci():
        numbers = []
        while True:
            if len(numbers) < 2:
                numbers.append(1)
                pass
            else:
                numbers.append(sum(numbers))
                pass
            yield numbers[-1]
        pass
    
    gen = fibonacci()
    for i in range(1, 10):
        print(next(gen))
    # 输出
    D:\Software\Installed\Python\Python36\python.exe D:/workspace/Pycharm/PurePythonProject/Test02.py
    1
    1
    2
    4
    8
    16
    32
    64
    128
    
    Process finished with exit code 0

3.2.2 终止生成器: StopIteration异常

  • Python 2中, 函数内不允许yield和return同时存在, 可以通过抛出StopIteration异常来终止生成器

    简单示例

    import sys
    
    print("Python版本信息: ", sys.version)

def generator(): yield 1 yield 2 raise StopIteration yield 3 pass

print([i for i in generator()])

gen = generator() while True: print(next(gen))

  **输出**

  ```python
  D:\Software\Installed\Python\Python36\python.exe D:/workspace/Pycharm/PurePythonProject/Test03.py
  Traceback (most recent call last):
  Python版本信息:  3.6.0 (v3.6.0:41df79263a11, Dec 23 2016, 08:06:12) [MSC v.1900 64 bit (AMD64)]
    File "D:/workspace/Pycharm/PurePythonProject/Test03.py", line 17, in <module>
  [1, 2]
      print(next(gen))
  1
    File "D:/workspace/Pycharm/PurePythonProject/Test03.py", line 9, in generator
  2
      raise StopIteration
  StopIteration

  Process finished with exit code 1
  • 从上例: 如果迭代这个生成器, 会得到1和2, 并可以正常退出(不抛出StopIterator异常); 如果使用next获取生成器的下一个值, 则会抛出StopIterator异常

  • Python 3中, 可以通过return语句终止生成器. 但是, return返回的值不会成为最终输出的值, 相反, 这个值会被作为异常信息发送. return语句实际等同于raise StopIteration

  • 简单示例

    import sys
    
    print("Python版本信息: ", sys.version)

def generator(): yield 1 yield 2 return 4 yield 3 pass

print([i for i in generator()])

gen = generator() while True: print(next(gen))

  **输出**

  ```shell
  D:\Software\Installed\Python\Python36\python.exe D:/workspace/Pycharm/PurePythonProject/Test04.py
  Python版本信息:  3.6.0 (v3.6.0:41df79263a11, Dec 23 2016, 08:06:12) [MSC v.1900 64 bit (AMD64)]
  [1, 2]
  1
  2
  Traceback (most recent call last):
    File "D:/workspace/Pycharm/PurePythonProject/Test04.py", line 17, in <module>
      print(next(gen))
  StopIteration: 4

  Process finished with exit code 1

3.3 与生成器之间的交互

  • 生成器协议提供了send方法, 以允许与生成器的反向沟通

简单示例

import sys

print("Python版本信息: ", sys.version)


def squares():
    a = 1
    b = 1
    while True:
        print('A: ', a, ' ', b)
        response = yield a + b
        print('B: ', a, ' ', b)
        if response:
            b = int(response)
        else:
            b += 1
        print('C: ', a, ' ', b)
    pass


sq = squares()
print(next(sq))
print(next(sq))
print(sq.send(7))
print(next(sq))

输出

D:\Software\Installed\Python\Python36\python.exe D:/workspace/Pycharm/PurePythonProject/Test04.py
Python版本信息:  3.6.0 (v3.6.0:41df79263a11, Dec 23 2016, 08:06:12) [MSC v.1900 64 bit (AMD64)]
A:  1   1
2
B:  1   1
C:  1   2
A:  1   2
3
B:  1   2
C:  1   7
A:  1   7
8
B:  1   7
C:  1   8
A:  1   8
9

Process finished with exit code 0

说明

  • send函数向生成器传递一个参数, 该参数为yield表达式的值

  • yield语句执行后暂停, 在下次调用时才会继续运行, 直到遇到下一条yield语句

3.4 迭代器对象与迭代器

  • Python中, 生成器是一种迭代器

  • Python中的迭代器是包含__next__方法的任何对象

  • 迭代对象 是任何定义了__iter__方法的对象, 可迭代对象的__iter__方法负责返回一个迭代器

  • 生成器可以是迭代器, 但不一定是迭代对象, 相似的, 并非所有的迭代对象都是迭代器

以range为例

  • range对象不是生成器, 因为range对象没有定义__next__函数, 不能作为next()函数的参数

  • 但是, range对象的__iter__方法返回的实际迭代器是一个生成器, 可以响应next方法. 但是不能响应send方法

    D:\workspace\Pycharm\PurePythonProject>python
    Python 3.6.0 (v3.6.0:41df79263a11, Dec 23 2016, 08:06:12) [MSC v.1900 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> r = range(0, 5)
    >>> r
    range(0, 5)
    >>> next(r)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: 'range' object is not an iterator
    >>> type(r)
    <class 'range'>
    >>> it = iter(r)
    >>> it
    <range_iterator object at 0x0000014A70D9AEF0>
    >>> next(it)
    0
    >>> next(it)
    1
    >>> it.send(2)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: 'range_iterator' object has no attribute 'send'
  • 语句for i in range(0, 5)之所以可以运行, 是因为range函数返回了一个迭代对象

  • 注意: 并非所有的迭代器都是generator类的实例. range迭代器是range_iterator的实例, 实现了相似的模式, 且缺少send方法 的实现

3.5 标准库中的生成器

3.5.1 range

  • 在Python 2中成为xrange

  • range对象的迭代器(由__iter__返回)是个生成器(range_iterator)

3.5.2 dict.items家族

  • 在Python中, 内置的字典类包括3个允许迭代所有字典的方法, 并且这3个方法都是迭代器是生成器的迭代对象(keys, values, items, 注意:在Python 2中, 三个方法分别是: iterkeys, itervalues, iteritems)

  • 把dict.items声明为生成器, 就不需要将整个字典重新格式化为包含键值的二元组列表

    简单示例

    D:\workspace\Pycharm\PurePythonProject>python
    Python 3.6.0 (v3.6.0:41df79263a11, Dec 23 2016, 08:06:12) [MSC v.1900 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> d = {'foo': 'bar', 'baz': 'bacon'}
    >>> it = iter(d.items())
    >>> next(it)
    ('foo', 'bar')
    >>> next(it)
    ('baz', 'bacon')
    >>> next(it)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    StopIteration
    >>>
  • 生成器返回所有数据后, 继续作为next函数的参数时, 会抛出StopIteraion异常

  • 在迭代期间修改字典, 可能会看到副作用

    D:\workspace\Pycharm\PurePythonProject>python
    Python 3.6.0 (v3.6.0:41df79263a11, Dec 23 2016, 08:06:12) [MSC v.1900 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> d = {'foo': 'bar', 'baz': 'bacon'}
    >>> it = iter(d.items())
    >>> next(it)
    ('foo', 'bar')
    >>> d['spam'] = 'eggs'
    >>> next(it)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    RuntimeError: dictionary changed size during iteration

3.5.3 zip

  • Python包含了一个名为zip的内置函数, 该函数有多个可迭代对象, 并且一起迭代所有对象

    D:\workspace\Pycharm\PurePythonProject>python
    Python 3.6.0 (v3.6.0:41df79263a11, Dec 23 2016, 08:06:12) [MSC v.1900 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> z = zip([1, 2, 3, 4], ['a', 'b', 'c'], ['A', 'B'])
    >>> next(z)
    (1, 'a', 'A')
    >>> next(z)
    (2, 'b', 'B')
    >>> next(z)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    StopIteration
  • 到达最短的迭代对象的最后一个元素时停止

3.5.4 map

  • map函数的参数为: 一个接受N个参数的函数, 以及N个迭代对象, 并且计算每个迭代对象的序列成员的函数结果, 到达最短的迭代对象的最后一个元素时停止

    D:\workspace\Pycharm\PurePythonProject>python
    Python 3.6.0 (v3.6.0:41df79263a11, Dec 23 2016, 08:06:12) [MSC v.1900 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> m = map(lambda x, y: x + y, [1, 2, 3], [4, 5])
    >>> next(m)
    5
    >>> next(m)
    7
    >>> next(m)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    StopIteration

3.5.5 文件对象

  • 可以利用生成器逐行读取文本文件内容

    D:\workspace\Pycharm\PurePythonProject>cat lines.txt
    line 1
    line 2
    line 3
    line 4
    line 5
    
    D:\workspace\Pycharm\PurePythonProject>python
    Python 3.6.0 (v3.6.0:41df79263a11, Dec 23 2016, 08:06:12) [MSC v.1900 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> f = open('lines.txt')
    >>> next(f)
    'line 1\n'
    >>> f.readline()
    'line 2\n'
    >>> next(f)
    'line 3\n'
    >>> f.readline()
    'line 4\n'
    >>> next(f)
    'line 5\n'
    >>> next(f)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    StopIteration
    >>> f.readline()
    ''
  • 由上面代码可以看出, next(f)和f.readline()语句的返回结果来自同一生成器对象, 但是, __next__函数(使用next(f)时会调用)和readline函数不完全一样, readline函数会捕捉StopIteration异常, 并返回一个空字符串

3.6 生成器单例模式

  • 简单的生成器函数并不是单例模式的, 多次调用函数将返回不同的生成器实例

    import sys
    
    print("Python版本信息: ", sys.version)

def fibonacci(): numbers = [] while True: if len(numbers) < 2: numbers.append(1) pass else: numbers.append(sum(numbers)) pass yield numbers[-1] pass

gen1 = fibonacci() print(next(gen1), next(gen1), next(gen1)) gen2 = fibonacci() print(next(gen2), next(gen2), next(gen2)) print(next(gen1), next(gen1), next(gen1))

  **输出**

  ```shell
  D:\Software\Installed\Python\Python36\python.exe D:/workspace/Pycharm/PurePythonProject/Test05.py
  Python版本信息:  3.6.0 (v3.6.0:41df79263a11, Dec 23 2016, 08:06:12) [MSC v.1900 64 bit (AMD64)]
  1 1 2
  1 1 2
  4 8 16

  Process finished with exit code 0
  • 下面的可迭代类可以实现类似单例模式的目的

    import sys
    
    print("Python版本信息: ", sys.version)
    
    class Fibonacci(object):
        def init(self):
            self.numbers = []
            pass
    
        def __iter__(self):
              return self
    
        def __next__(self):
            if len(self.numbers) < 2:
                self.numbers.append(1)
                pass
            else:
                self.numbers.append(sum(self.numbers))
                self.numbers.pop(0)
                pass
            return self.numbers[-1]
    
        def send(self, value):
            pass
    
        # 兼容 Python 2
        next = __next__
        pass
    
      f = Fibonacci()
      i1 = iter(f)
      print(next(i1), next(i1), next(i1))
      i2 = iter(f)
      print(next(i2))

输出

D:\Software\Installed\Python\Python36\python.exe D:/workspace/Pycharm/PurePythonProject/Test05.py
  Python版本信息:  3.6.0 (v3.6.0:41df79263a11, Dec 23 2016, 08:06:12) [MSC v.1900 64 bit (AMD64)]
  1 1 2
  3

  Process finished with exit code 0

3.7 生成器内部的生成器

  • 一个生成器调用另外一个生成器是可行的

  • Python 3.3引入了新的yield from语句, 旨在为生成器提供一种调用其他生成器的直接方式

    简单示例

    import sys
    import itertools
    
    print("Python版本信息: ", sys.version)
    
    def gen1():
        yield 'foo'
        yield 'bar'
        pass
    
    def gen2():
        yield 'spam'
        yield 'eggs'
        pass

第一种调用方式

def full_gen_1(): for word in gen1(): yield word pass for word in gen2(): yield word pass pass

第二种调用方式, 使用 itertools.chain

def full_gen_2(): for word in itertools.chain(gen1(), gen2()): yield word pass pass

第三种调用方式, 使用 yield from 语句

def full_gen_3(): yield from gen1() yield from gen2() pass

print([i for i in full_gen_1()]) print([i for i in full_gen_2()]) print([i for i in full_gen_3()])

  **输出**

  ```shell
  D:\Software\Installed\Python\Python36\python.exe D:/workspace/Pycharm/PurePythonProject/Test06.py
  Python版本信息:  3.6.0 (v3.6.0:41df79263a11, Dec 23 2016, 08:06:12) [MSC v.1900 64 bit (AMD64)]
  ['foo', 'bar', 'spam', 'eggs']
  ['foo', 'bar', 'spam', 'eggs']
  ['foo', 'bar', 'spam', 'eggs']

  Process finished with exit code 0
  • yield from被称为生成器委托

  • 使用yield from时, 该生成器委托给另一个生成器, 任何使用send函数发送个生成器的值, 都将被发送给当前委托生成器. 而前两种实现, 则需要手动传递该值.

上一页BookNotes下一页垃圾回收机制

最后更新于4年前

这有帮助吗?