装饰器:本质就是函数,功能是:为其它函数添加附加功能
一,原则:
1.不修改被修饰函数的源代码
2.不修改被修饰函数的调用方式
二,装饰器的组成:
装饰器=高阶函数+函数嵌套+闭包
1,高阶函数定义:
1函数接收的参数是一个函数名
2函数的返回值是一个函数名
3满足以上任意一个,都可以称为高阶函数
2,函数嵌套:
定义函数里面还有定义函数
3,闭包:
嵌套函数里的某个函数包含着变量,函数下面还有一层函数,那一层函数里也包含着变量,这些情况都可以叫闭包(了解一下作用域)
代码
1高阶函数
#装饰器的目的: # 1不修改被修饰函数的源代码, # 2适用于多个函数(复用性), # 3不修改被装饰的函数的调用方式 # #先定义一个函数(特点:二个参) def say_to_sky(name,content): print("我是%s,我对天空大声喊:%s" %(name,content)) #定义另一个函数(特点:一个参) def say_to_mysself(name): print("我是%s" %name) #定义第三个函数(特点:无参) def say_to_you(): print("你好啊啊啊") # 定义第四个函数(特点:无参) def say_to_mama(): print("妈妈好啊")
import time ###########111################ #(装饰器未完成状态1)能达成的目的: # 1不修改被修饰函数的源代码 def timer1(): begin_time = time.time() #函数运行时间太短,让它睡一会,增加时间比较直观 time.sleep(2) say_to_mama() end_time = time.time() print("程序运行耗时:",end_time - begin_time,"秒") ############111############### #(装饰器未完成状态1)能达成的目的: # 1不修改被修饰函数的源代码 # (发现要装饰多个函数的时候,重复代码太多了,没有复用性,想到高阶函数) def timer2(): begin_time = time.time() #函数运行时间太短,让它睡一会,增加时间比较直观 time.sleep(2) say_to_you() end_time = time.time() print("程序运行耗时:",end_time - begin_time,"秒") ############222######## #(装饰器未完成状态2)能达成的目的: # 1不修改被修饰函数的源代码, # 2适用于多个函数(复用性) #利用高阶函数来处理 复用性的问题 #函数接收的参数是一个函数名 def timer3(func): begin_time = time.time() # 函数运行时间太短,让它睡一会,增加时间比较直观 time.sleep(2) #打印为什么是None,因为函数无返回值 print(func()) end_time = time.time() print("程序运行耗时:", end_time - begin_time, "秒") #下面的函数的调用,功能是有扩展了,但是违反了开放封闭原则,修改了函数的调用方式 timer1()#违反开放封闭原则 timer2()#违反开放封闭原则 say_to_mama()#调用方式是没变,也无附加功能,和我们的目的相违背 timer3(say_to_mama)#违反开放封闭原则 timer3(say_to_you)#违反开放封闭原则 ############333########################## #利用高阶函数来处理 开放封闭原则的问题 #函数的返回值是一个函数 def timer4(func): begin_time = time.time() time.sleep(2) print("-"*30) func() end_time = time.time() print("程序运行耗时:", end_time - begin_time, "秒") return func say_to_mama = timer4(say_to_mama) # 虽然调用say_to_mama()没变,但是实际执行多了一次,不符合要求 #高阶函数的2个方法都已经用了,没辙了,高阶函数满足不了 装饰器的功能 实现 say_to_mama()
函数嵌套
#函数嵌套 #了解变量作用域 def father(name): print("from father %s" %name) def son(): print("from son %s" %name) def grandson(): name = "孙子" print("from grandson %s" %name) grandson() #打印当前层的局部变量(son也是局部变量) print(locals()) son() father("詹")
函数闭包
#函数闭包装饰器的基本实现(我咋觉得就是高阶函数+函数嵌套呢) def timmer(func): def wrapper(): begin_time = time.time() func() end_time = time.time() print("程序运行耗时:", end_time - begin_time, "秒") return wrapper @timmer #相当于 sayHi = timmer(sayHi) def sayHi(): time.sleep(2) print("Hello world world") #sayHi = timmer(sayHi)#返回的是wrapper的地址 sayHi()#执行的是wrapper(),只执行一次,满足不改变原代码调用方式
函数闭包+返回值 (被装饰函数的返回值,假设上面代码的装饰器不改,被装饰函数的返回值就不会有,只会是None,因为返回的是wrapper的返回值,wrapper没有返回值,下面的代码给wrapper加上返回值即可)
#函数闭包装饰器的基本实现(我咋觉得就是高阶函数+函数嵌套呢) def timmer(func): def wrapper(): begin_time = time.time() res = func() end_time = time.time() print("程序运行耗时:", end_time - begin_time, "秒") return res return wrapper @timmer #相当于 sayHi = timmer(sayHi) def sayHi(): time.sleep(2) print("Hello world world") return "我是sayHi函数" #sayHi = timmer(sayHi)#返回的是wrapper的地址 print(sayHi())#执行的是wrapper(),只执行一次,满足不改变原代码调用方式
函数闭包+参数
#函数闭包装饰器的基本实现(我咋觉得就是高阶函数+函数嵌套呢) def timmer(func): def wrapper(*args,**kwargs): begin_time = time.time() res = func(*args,**kwargs) end_time = time.time() print("程序运行耗时:", end_time - begin_time, "秒") return res return wrapper @timmer #相当于 sayHi = timmer(sayHi) def sayHi(name,content): time.sleep(2) return "我是sayHi函数,是%s写的,我想说%s" %(name,content) #sayHi = timmer(sayHi)#返回的是wrapper的地址 print(sayHi("詹","大吉大利!!!"))#执行的是wrapper(),只执行一次,满足不改变原代码调用方式
序列解压:
举例:
a,b,c, = [2,3,4] c,d,e, = (2,3,4) f,g,h, = "abc" i,j= {"name":"james","age":18} print(a,b,c,d,e,f,g,h,i,j,) z,t,*x,y,l = [1,2,3,4,5,6,7,"f",23,"我们"] print(z,t,y,l) a1 = 5 b1 = 6 a1,b1 = b1,a1 print(a1,b1)