python基础:迭代器生成器面向过程编程
Posted zhangshuyuan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python基础:迭代器生成器面向过程编程相关的知识,希望对你有一定的参考价值。
-
迭代器
-
生成器
-
面向对线编程
一 迭代器
#1、为何要有迭代器? 对于序列类型:字符串、列表、元组,我们可以使用索引的方式迭代取出其包含的元素。但对于字典、集合、文件等类型是没有索引的,若还想取出其内部包含的元素,则必须找出一种不依赖于索引的迭代方式,这就是迭代器 #2、什么是可迭代对象? 可迭代对象指的是内置有__iter__方法的对象,即obj.__iter__,如下 ‘hello‘.__iter__ (1,2,3).__iter__ [1,2,3].__iter__ {‘a‘:1}.__iter__ {‘a‘,‘b‘}.__iter__ open(‘a.txt‘).__iter__ #3、什么是迭代器对象? 可迭代对象执行obj.__iter__()得到的结果就是迭代器对象 而迭代器对象指的是即内置有__iter__又内置有__next__方法的对象 文件类型是迭代器对象 open(‘a.txt‘).__iter__() open(‘a.txt‘).__next__() #4、注意: 迭代器对象一定是可迭代对象,而可迭代对象不一定是迭代器对象
#常配合for循环使用,我们可以完全不再依赖索引去取值了 dic={‘a‘:1,‘b‘:2,‘c‘:3} for k in dic: print(dic[k]) #for循环的工作原理 #1:执行in后对象的dic.__iter__()方法,得到一个迭代器对象iter_dic #2: 执行next(iter_dic),将得到的值赋值给k,然后执行循环体代码 #3: 重复过程2,直到捕捉到异常StopIteration,结束循环
#优点: - 提供一种统一的、不依赖于索引的迭代方式 - 惰性计算,节省内存 #缺点: - 无法获取长度(只有在next完毕才知道到底有几个值) - 一次性的,只能往后走,不能往前退
二 生成器
#只要函数内部包含有yield关键字,那么函数名()的到的结果就是生成器,并且不会执行函数内部代码 def func(): print(‘====>first‘) yield 1 print(‘====>second‘) yield 2 print(‘====>third‘) yield 3 print(‘====>end‘) a = func() print(next(a)) # ====>first # 1 print(next(a)) # ====>second # 2 print(next(a)) #====>third # 3 b = func() for i in b: print(i) # ====>first # 1 # ====>second # 2 # ====>third # 3 # ====>end
# 生成器就是迭代器,__iter__方法返回生成器本身,__next__方法执行到函数下一个yield关键字处 def func2(n): for i in range(n): yield i >>> a = func2(4) >>> b = a.__iter__() >>> b <generator object func2 at 0x000001B28DB82410> >>> a <generator object func2 at 0x000001B28DB82410>
练习
# 1.使用生成器模拟range(1, 7, 2) def my_range(start, end, step=1): while start < end: yield start start += step for i in my_range(1, 7, 2): print(i) # 2. 使用生成器模拟linex系统管道 # cat db.txt | grep ‘user‘ def get_lines(filepath): with open(filepath, ‘r‘, encoding=‘utf-8‘) as f: while True: line = f.readline() if line: yield line else: break def grep(target, lines): result = [] for line in lines: if target in line: result.append(line) return result print(grep(‘user‘, get_lines(‘D:oldboy_pythonpython基础day15db.txt‘)))
携程函数
def eater(name): print(‘%s start to eat food‘ % name) food_list = [] while True: food = yield food_list print(‘%s get %s ,to start eat‘ % (name, food)) food_list.append(food) e = eater(‘钢蛋‘) print(next(e)) # 钢蛋 start to eat food # [] print(e.send(‘包子‘)) # 钢蛋 get 包子 ,to start eat # [‘包子‘] print(e.send(‘韭菜馅包子‘)) # 钢蛋 get 韭菜馅包子 ,to start eat # [‘包子‘, ‘韭菜馅包子‘] print(e.send(‘大蒜包子‘)) # 钢蛋 get 大蒜包子 ,to start eat # [‘包子‘, ‘韭菜馅包子‘, ‘大蒜包子‘]
# 携程函数的装饰器,利用装饰器函数进行首次next(func) def init(func): def wrapper(*args, **kwargs): res = func(*args, **kwargs) next(res) return res return wrapper @init def eater(name): print("%s eat food" % name) food_list = [] while True: food = yield food_list print("%s star to eat %s" % (name, food)) food_list.append(food) g = eater("gangdan") # 不需要使用next初始化 print(g.send("1")) print(g.send("2")) print(g.send("3")) print(g.send("4"))
携程函数的应用
>>> import os >>> os.walk(‘D: est‘) generator object walk at 0x0000000002ADB3B8 >>> os.walk(r‘D: est‘) # 使用r 是让字符串中的符号没有特殊意义,针对的是转义
# 可以用inspect.getgeneratorstate(generator)查看携程的状态
# 练习 实现功能:grep -rl ‘python‘ /etc # 面向过程编程 # 使用装饰器对携程函数初始化 # 函数自上向下进行,通过send自上向下传递参数 # yield向上返回tag,cat函数一旦得到res为True则停止搜索 # grep函数一旦发现pattern则向printer函数send目标路径并修改tag import os def init(func): def wrapper(*args, **kwargs): g = func(*args, **kwargs) next(g) return g return wrapper @init def search(target): while True: filepath = yield g = os.walk(filepath) for dirname, _, files in g: for file in files: abs_path = os.path.join(dirname, file) target.send(abs_path) @init def opener(target): while True: filepath = yield with open(filepath, ‘rb‘) as f: target.send((f, filepath)) @init def cat(target): while True: f, abs_path = yield for line in f: res = target.send((line, abs_path)) if res: break @init def grep(pattern, target): tag = False while True: line, abs_path = yield tag tag = False if pattern.encode(‘utf-8‘) in line: target.send(abs_path) tag = True @init def printer(): while True: abs_path = yield print(abs_path) g = search(opener(cat(grep(‘user‘, printer())))) g.send(r‘D:oldboy_pythonpython基础day15‘)
以上是关于python基础:迭代器生成器面向过程编程的主要内容,如果未能解决你的问题,请参考以下文章