Python的生成器进阶玩法
Python的生成器进阶玩法
作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
一.yield的表达式形式
#!/usr/bin/env python
#_*_coding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
#EMAIL:y1053419035@qq.com def foo():
print("starting")
while True:
print("=======")
x = yield #将yield的返回值进行赋值操作,我们可以称之为生成器表达式
print("value:%s"% x ) g = foo()
# print(g)
next(g) #Next方法默认是不传值的,生成器第一次传值传值必须为空(g.send(None) ),
# 否则就会报错(TypeError: can't send non-None value to a just-started generator),一次传None值的操作我们称之为初始化。 g.send(100) #相比next方法多了一个传值操作,即把100传给生成器g中的yield。 g.send(None) #如果传值(send)为空(None)则等同于next(g)方法。 #以上代码执行结果如下:
starting
=======
value:100
=======
value:None
=======
二.生成器初始化传值操作
#!/usr/bin/env python
#_*_coding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
#EMAIL:y1053419035@qq.com import time def InitializationValue(func): #定义一个装饰器对生成器进行初始化操作。
def wrapper(*args,**kwargs):
g = func(*args,**kwargs)
try:
next(g) #进行生成器传值的初始化操作,这样用户就可以第一次进行传值(因为Next方法默认是不传值的,生成器第一次传值传值必须为空(g.send(None) ))
except TypeError:
pass
return g
return wrapper @InitializationValue
def consumer(name):
# print("%s 准备吃饺子啦!"% name)
while True:
dumplings = yield
print("饺子[%s]来了,被[%s]吃了!"% (dumplings,name)) @InitializationValue
def producer(name):
c = consumer("yinzhengjie")
# print("俺要开始准备吃饺子了!")
for i in range(1,10):
time.sleep(1)
print("%s做的第%s个饺子"%(name,i))
c.send(i)
producer("尹正杰") #以上代码执行结果如下:
尹正杰做的第1个饺子
饺子[1]来了,被[yinzhengjie]吃了!
尹正杰做的第2个饺子
饺子[2]来了,被[yinzhengjie]吃了!
尹正杰做的第3个饺子
饺子[3]来了,被[yinzhengjie]吃了!
尹正杰做的第4个饺子
饺子[4]来了,被[yinzhengjie]吃了!
尹正杰做的第5个饺子
饺子[5]来了,被[yinzhengjie]吃了!
尹正杰做的第6个饺子
饺子[6]来了,被[yinzhengjie]吃了!
尹正杰做的第7个饺子
饺子[7]来了,被[yinzhengjie]吃了!
尹正杰做的第8个饺子
饺子[8]来了,被[yinzhengjie]吃了!
尹正杰做的第9个饺子
饺子[9]来了,被[yinzhengjie]吃了!
三.面向过程编程案例
#!/usr/bin/env python
#_*_coding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
#EMAIL:y1053419035@qq.com
import os def init(func):
def wrapper(*args,**kwargs):
g = func(*args,**kwargs)
next(g)
return g
return wrapper #阶段一:递归找文件的绝对路径,把路径发给阶段二
@init
def Search(Target):
"sercg files abapath"
while True:
StartPath = yield
g = os.walk(StartPath)
for ParDir, _, files in g: # 注意,ParDir是父目录,其中“_"是父目录下的子目录,“files”则是父目录下的所有子文件!
for file in files:
FilePath = r"%s\%s" % (ParDir, file)
Target.send(FilePath) #阶段二:收到文件路径,打开文件获取文件对象吗,把文件对象发给截断三;
@init
def Opener(Target):
"get file obj :f = open(filepath)"
while True:
FilePath = yield
with open(FilePath,encoding="utf-8")as f:
Target.send((FilePath,f)) #阶段三:收到文件对象,for循环读取文件的每一行内容,把每一行内容发给阶段四;
@init
def Cat(Target):
"read file"
while True:
FilePath,f = yield
for line in f:
res = Target.send((FilePath,line))
if res:
break
#阶段四:收到一行内容,判断root是否在这一行中,如果在,则把文件名发给阶段五;
@init
def Grep(Target,Pattern):
"grep function"
tag = False
while True:
FilePath,line = yield tag #我们用tag来标记是否找到文件名,如果找到了就为True
tag = False
if Pattern in line:
Target.send(FilePath)
tag = True
#阶段五:收到文件名,并打印结果;
@init
def Printer():
"parint function"
while True:
Filename = yield
print(Filename) Startpath = r"E:\Code\pycharm\文件存放处\python学习笔记\DAY7"
g = Search(Opener(Cat(Grep(Printer(),"yinzhengjie")))) print(g) g.send(Startpath) """
经过上面的程序课件yield表达式形式有以下特征:
面向过程的程序设计思想:
核心是:过程,过程就是流程
优点:
1>.思路清晰;
2>.复杂的问题简单化;
3>.流程化;
缺点:
1>.扩展性差
应用:
1>.Linux内核;
2>.httpd;
3>.git;
""” #以上代码执行结果如下:
<generator object Search at 0x02A02450>
E:\Code\pycharm\文件存放处\python学习笔记\DAY7\1.yield的表达式形式.py
E:\Code\pycharm\文件存放处\python学习笔记\DAY7\2.生成器初始化传值操作.py
E:\Code\pycharm\文件存放处\python学习笔记\DAY7\3.面向过程编程-用生成器模拟grep功能.py
E:\Code\pycharm\文件存放处\python学习笔记\DAY7\access.log
Python的生成器进阶玩法的更多相关文章
- Python列表推导式玩法
前言 列表做为python的基础,是必须学习的语法之一.一些基础的之前已经是反复温习和使用了,今天我们来学习它的进阶版-->列表推导式. 列表推导式: 优点:是将所有的值一次性加载到内存中,相比 ...
- python 各种推导式玩法
推导式套路 除了最简单的列表推导式和生成器表达式,其实还有字典推导式.集合推导式等等. 下面是一个以列表推导式为例的推导式详细格式,同样适用于其他推导式. variable = [out_exp_re ...
- WPF 3D球及进阶玩法
在WPF中3D球的构建算法请参考: https://www.cnblogs.com/lonelyxmas/p/9844951.html 好玩以及值得借鉴的Demo: (CSDN下载需要积分,避免你 ...
- PHP进阶玩法
1. 删除不必要的模块. PHP随带内置的PHP模块.它们对许多任务来说很有用,但是不是每个项目都需要它们.只要输入下面这个命令,就可以查看可用的PHP模块: # php - m 一旦你查看了列表, ...
- Python之生成器及内置函数篇4
一.可迭代对象 #1.什么是迭代?:迭代是一个重复的过程,并且每次重复都是基于上一次的结果而来 #2.可迭代的对象:在python中,但凡内置有__iter__方法的对象,都是可迭代的对象 #3.迭代 ...
- 超详细的格式化输出(format的基本玩法)
一.format的基本玩法 一.什么是format format是字符串内嵌(字符串内嵌:字符串中再嵌套字符串,加入双引号或单引号)的一个方法,用于格式化字符串.以大括号{}来标明被替换的字符串 fo ...
- 【Python基础】random 的高级玩法
random 模块的高级玩法 1.python 随机产生姓名 方式一: import random xing = [ '赵', '钱', '孙', '李', '周', '吴', '郑', '王', ' ...
- 十三. Python基础(13)--生成器进阶
十三. Python基础(13)--生成器进阶 1 ● send()方法 generator.send(value) Resumes the execution, and "sends&qu ...
- python基础(9)-迭代器&生成器函数&生成器进阶&推导式
迭代器 可迭代协议和迭代器协议 可迭代协议 只要含有__iter__方法的对象都是可迭代的 迭代器协议 内部含有__next__和__iter__方法的就是迭代器 关系 1.可以被for循环的都是可迭 ...
随机推荐
- R语言学习 第三篇:数据框
数据框(data.frame)是最常用的数据结构,用于存储二维表(即关系表)的数据,每一列存储的数据类型必须相同,不同数据列的数据类型可以相同,也可以不同,但是每列的行数(长度)必须相同.数据框的每列 ...
- effective c++ 笔记 (1-3)
// // effective c++.cpp // 笔记 // // Created by fam on 15/3/23. // // //-------------------------- ...
- 初级字典树查找在 Emoji、关键字检索上的运用 Part-3
系列索引 Unicode 与 Emoji 字典树 TrieTree 与性能测试 生产实践 生产实践 我们最终要解决 Emoji 在浏览器和打印物上的显示一致. 进行了多番对比,,在显示效果和精度上,m ...
- Unity光照与渲染设置学习笔记
学习了一下unity中有关光照和渲染的一些设置,现在才明白之前遇到的一些问题只是没有正确设置而已. unity不同版本的光照设置会有一些差异,而且可以调节的参数非常多,这里只记录一些重要的参数和使用方 ...
- 智能合约bug以及修改方案
截取两篇文章:第一遍文章说的是智能合约能不能修改的问题: ETC转到ETH地址以及转币进ETH智能合约账户能不能转出来? 第0章 引言 如果ETC充值到了ETH地址上,能找回来吗?答案是不一定. ET ...
- JSP JSTL知识结构图
自行绘制,欢迎指正.
- [2017BUAA软工助教]学期总结
一.表 学号 第0次 week1 week2 week3 个人项目 附加1 结对项目 附加2 a团队得分 a贡献分 b团队得分 b贡献分 阅读作业 提问回顾 总分1 总分2 14011100 8 8 ...
- Win7(及以后版本) 高级搜索 AND OR NOT 正则
http://www.cnblogs.com/include/archive/2011/08/23/2150594.html TIP:语法容易混淆,容易误用用C系列语法 & | !等,其实是S ...
- Docker(十)-Docker创建DockerFile文件
制作Docker image 有两种方式: 使用 Docker container,直接构建容器,再导出成 image 使用. 是使用 Dockerfile,将所有动作写在文件中,再 build 成 ...
- Vue实现对数组、对象的深拷贝、复制
当组件间传递对象时,由于此对象的引用类型指向的都是一个地址(除了基本类型跟null,对象之间的赋值,只是将地址指向同一个,而不是真正意义上的拷贝),如下 数组: ,,]; var b = a; b.p ...