一、装饰器:
定义:本质是函数,为其他函数添加附加功能
原则:不能修改被装饰的函数的源代码和调用方式
实现装饰器的知识储备:
1.函数就是“变量”
2.高阶函数
- 把一个函数名(门牌号相当于内存地址)当做实参传给另一个函数
- 返回值必须包含函数名
3.函数嵌套(闭包):在函数体内用def声明一个函数
1 def foo(): 2 print('in the foo') 3 def bar(): 4 print('in the bar') 5 6 bar() #必须要调用这个函数才能运行内部的函数,所以在装饰器中必须要return内部的函数名称才能调用 7 foo()
高阶函数 + 嵌套函数 = 装饰器
1 import time
2
3 def timer(func): 4 def doc(*args,**kwargs): 5 start_time=time.time() 6 func(*args,**kwargs) 7 stop_time=time.time() 8 print("运行耗时%s"%(stop_time-start_time)) 9 return doc 10 11 @timer #==不需要修改调用方式,直接走装饰器里面的函数,来达到增加功能的作用 12 def test1(): 13 time.sleep(3) 14 print("in the test1") 15 16 @timer 17 def test2(*args,**kwargs): 18 print("test2:",*args,**kwargs) 19 20 21 test1() 22 test2("alex",[1,2,3,4],{"alex":[15,51,"scinjks"],"yjx":15})
return值的问题
1 username,password="alex","abc123" 2 def auth(func): 3 def doc(*args,**kwargs): 4 user_input_username=input("请输入用户名:") 5 user_input_password=input("请输入密码:") 6 if user_input_username==username and user_input_password==password: 7 func(*args,**kwargs) #=运行下面的那个函数的返回值,so要return这个返回值到doc的函数。。实际上经过这一串操作。home()=doc() 8 print("welcom back %s"%user_input_username) 9 return func(*args,**kwargs) 10 else: 11 exit() 12 13 return doc 14 15 def index(): 16 print("welcom to index page") 17 @auth 18 def home(): 19 print("welcom to home page") 20 return "from home" 21 @auth 22 def bbs(): 23 print("welcom to bbs page") 24 25 26 index() 27 print(home()) 28 bbs()
终极版(添加判断)
1 username,password="alex","abc123" 2 def auth(auth_type): 3 def outer_wrapper(func): #就这么写吧,加一级。我也不知道为什么 4 def doc(*args,**kwargs): 5 if auth_type=="local": 6 user_input_username=input("请输入用户名:") 7 user_input_password=input("请输入密码:") 8 if user_input_username==username and user_input_password==password: 9 print("welcom back %s"%user_input_username) 10 return func(*args,**kwargs) #=运行下面的那个函数的返回值,so要return这个返回值到doc的函数。。实际上经过这一串操作。home()=doc() 11 #return func(*args,**kwargs) 12 else: 13 exit() 14 elif auth_type=="ldap": 15 print("ldap,我不会.00.00") 16 return doc 17 return outer_wrapper 18 19 def index(): 20 print("welcom to index page") 21 @auth(auth_type="local") 22 def home(): 23 print("welcom to home page") 24 #return "from home" 25 @auth(auth_type="ldap") 26 def bbs(): 27 print("welcom to bbs page") 28 29 30 index() 31 home() 32 bbs()
装饰器(易记忆版):
def inner(func):
def doc(*args,**kwargs):
运行函数前要干的事
func(*args,**kwargs) # 执行函数
函数运行完之后要干的事
return doc
@inner
def func(a,b):
pass
二、迭代器
迭代器是访问集合元素的一种方式。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退。另外,迭代器的一大优点是不要求事先准备好整个迭代过程中所有的元素。迭代器仅仅在迭代到某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁(Python在迭代过程中不能删除列表/字典中的元素)。这个特点使得它特别适合用于遍历一些巨大的或是无限的集合,比如几个G的文件
特点:
- 访问者不需要关心迭代器内部的结构,仅需通过next()方法不断去取下一个内容
- 不能随机访问集合中的某个值 ,只能从头到尾依次访问
- 访问到一半时不能往回退
- 便于循环比较大的数据集合,节省内存
列表生成式:
g = [x * x for x in range(10)] #将列表生成式的[]改成()就好了
print(g)
>> [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
迭代器:将列表生成式的[]改成()就好了
L = (x * x for x in range(10))
print(L)
>> <generator object <genexpr> at 0x00000267957AD0F8> #保存的是一个算法
输出方式:
#一种输出值的方式:一直print(next(L))
print(next(L)) # 或print(L.__next__())
>> 0 1 4 9 16 25 36 49 64 81
#第二种输出方式
for i in L:
print(i)
>> 0 1 4 9 16 25 36 49 64 81
三、生成器:
一个函数调用时返回一个迭代器,那这个函数就叫做生成器(generator);如果函数中包含yield语法,那这个函数就会变成生成器;
def fib(max): # 斐波那契数列
n,a,b = 0,0,1
while n < max:
yield b
a,b = b,a+b
n += 1
return 'done'
输出值的方法:
方法一:
data=fib(10)
print(data.__next__()) #相当于print(next(data))
print(data.__next__())
print(data.__next__())
print(data.__next__())
print(data.__next__())
print(data.__next__())
print(data.__next__())
>> 1 1 2 3 5 8 13
方法二:
data=fib(10)
for i in data: #Python的for循环本质上就是通过不断调用next()函数实现的
print(i)
>> 1 1 2 3 5 8 13 21 34 55
Python的for循环本质上就是通过不断调用next()函数实现的
1 for x in [1, 2, 3, 4, 5]:
2
3 pass 4 5 完全等价于 6 7 # 首先获得Iterator对象: 8 it = iter([1, 2, 3, 4, 5]) 9 # 循环: 10 while True: 11 try: 12 # 获得下一个值: 13 x = next(it) 14 except StopIteration: 15 # 遇到StopIteration就退出循环 没有return的返回值 16 break
方法三:(可以返回return的值)
1 def fib(max):
2 n,a,b = 0,0,1
3
4 while n < max: 5 #print(b) 6 yield b #保存函数的中断状态 并返回值 7 a,b = b,a+b 8 9 n += 1 10 return 'done' 11 g = fib(6) 12 while True: 13 try: 14 x = next(g) # g.__next__() 15 print('g:', x) 16 except StopIteration as e: 17 print('Generator return value:', e.value) 18 break
>> g: 1 g: 1 g: 2 g: 3 g: 5 g: 8 Generator return value: done