一、装饰器
1.函数即“变量”
2.高阶函数
把一个函数名当作实参传给另外一个函数(不修改被装饰函数代码的情况下为其添加新功能);
返回值中包含函数名(不修改原函数的调用方式);
3.嵌套函数
在函数体内用def定义一个函数
####装饰器一####
import time
def timer(func): # 这一层用来传函数
def deco(*args,**kwargs): # 这一层用来传函数内的参数
start_time = time.time()
func(*args,**kwargs)
end_time = time.time()
print('一共用时%f秒'%(end_time-start_time))
return deco # 不加这层则test1=timer(test1)接收不到返回值报错
@timer # test1 = timer(test1)
def test1():
time.sleep(1)
print('hello,world!')
@timer
def test2(name): # 带参数
time.sleep(1)
print('hello,%s!'%name)
test1()
test2('Tony')
# t = timer(test1)
# print(t())
####装饰器2####
user1 = 'aaa'
password1 = '111'
user2 = 'bbb'
password2 = '222'
def auth(person): # 这一层用来选角色
def out_wrap(func): # 这一层用来传函数
def wrap(*args,**kwargs): # 这一层用来传函数内的参数
if person == 1:
name = input('请输入用户名:')
passwd = input('请输入密码:')
if name == user1 and passwd == password1:
func(*args,**kwargs)
else:
exit('账户名或密码有误!!')
elif person == 2:
name = input('请输入用户名:')
passwd = input('请输入密码:')
if name == user2 and passwd == password2:
func(*args, **kwargs)
else:
exit('账户名或密码有误!!')
return wrap
return out_wrap
def home():
print('welcome home')
@auth(person=1)
def page1():
print('welcome to page1')
@auth(person=2)
def page2(name):
print('welcome to page2,%s'%name)
# home()
# page1()
page2('Eason')
# 要实现不同角色进入页面打印不同名字,则需要在装饰器内部加一行打印,这个例子只是想要源代码不变且调用方式不变
二、 生成器
a = [i*2 for i in range(10)] # 列表生成式
b = (i*2 for i in range(10)) # 生成器,只能进行简单的逻辑操作
注:b.__next__() == next(b)
1. 用函数做生成器,只需在函数里加入yield即可,可进行复杂的逻辑操作
2. 有yield时,return返回值是异常的消息,可以被e.value捕捉到
3. 通过生成器可以实现并行效果
import time
def consumer(name):
print('%s 准备吃寿司'%name)
while True:
sushi = yield # 使生成器中断
print('寿司[%s]来了,被[%s]吃了'%(sushi,name))
# c = consumer('Eason')
# c.__next__()
# b1 = '1'
# c.send(b1)
def producer(name):
c = consumer('Tony') # 创建一个对象,生成器不往下走
c2 = consumer('Eason')
c.__next__() # 执行了这步才打印“Tony准备吃寿司”
next(c2) # 这句跟上面一句相同
print('%s 准备做寿司啦!'%name)
for i in range(5):
time.sleep(1)
print('\n做了2个寿司')
c.send(i) # 在外部把值传进生成器c,传给consumer里的变量sushi
c2.send(i)
producer('Ashome')
三、 迭代器:python的迭代器对象表示的是一个数据流
可直接作用与for循环的对象称为可迭代对象(Iterable),直接作用与for循环的数据类型有以下几种:
- 集合数据类型,如list,tuple,dict,set,str等
- generator,包括生成器和带yield的generator function
可被next()调用并不断返回下一个值的对象称为迭代器(Iterator)
可用isinstance()判断是否为Iterable对象和Iterator对象:
from collections import Iterable
from collections import Iterator
1. 生成器是一个迭代器
2. 用iter()把list,dict,str变成迭代器
3. range()函数返回一个迭代器