生成器
在 Python 中,使用了 yield 的函数被称为生成器(generator)。
跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。
在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。
调用一个生成器函数,返回的是一个迭代器对象。
def generator(): print(1) yield 'a' print(2) yield 'b' print(3) yield 'b' ret = generator() print(ret.__next__()) print(ret.__next__()) print(ret.__next__()) for i in ret: print(i)
用三次next方法执行和for循环执行这个生成器结果是一样的
# 只要含有yield 的函数都是生成器函数
# yield 和return 不能共用
# 生成器函数:执行之后会得到一个生成器作为返回值
生成器的简单应用:
做一个简单的文件监听器
函数方法:
def tail(filename): with open(filename,encoding='utf-8') as f: while True: line = f.readline() if line.strip(): print(line.strip()) tail('file')
这个方法虽然能够满足我们监听文件的功能。但是如果我们需要对监听到的行进行操作呢?需要修改原函数,不满足开放封闭原则
例如:我们只想取包含python关键字的行,
例如:我们想对新生成的行进行修改
用生成器的方法:
def tail(filename): with open(filename,encoding='utf-8') as f: while True: line = f.readline() if line.strip(): yield line.strip() ret = tail('file') # 这是我们就拿到了一个生成器 ret,可以对他进行一系列操作。此时我们也可以接着监控我们的文件。 # print('***',ret.__next__()) # 这里对新的一行进行操作 # for i in ret: # print('***',i) for i in ret: if 'python' in i: print('这是我想要的关键字:',i) # 这里我们取到关键字的行并修改。且没有修改原函数
这是我想要的关键字: ssspython
这是我想要的关键字: hello,python
wraps
from functools import wraps def wrapper(func): #func = holiday @wraps(func) # 带参数的装饰器 def inner(*args,**kwargs): print('在被装饰的函数执行之前做的事') ret = func(*args,**kwargs) print('在被装饰的函数执行之后做的事') return ret return inner @wrapper #holiday = wrapper(holiday) def holiday(day): '''这是一个放假通知''' print('全体放假%s天'%day) return '好开心' print(holiday.__name__) print(holiday.__doc__) ret = holiday(3) #inner print(ret) # 带参数的装饰器不会影响装饰器函数与被装饰函数的打印,很厉害 # def wahaha(): # ''' # 一个打印娃哈哈的函数 # :return: # ''' # print('娃哈哈') # print(wahaha.__name__) #查看字符串格式的函数名 # print(wahaha.__doc__) #查看函数注释