Day11 of learning python--装饰器
1.三元运算
公式:变量=条件返回True结果 if条件 else 条件返回False的结果
例子:写函数,接收两个数字参数,返回比较大的那个数字
1 def func(a,b): 2 return a if a > b else b 3 print(func(1,4))
2.装饰器的形成过程:最简单的装饰器,到有返回值的,有一个参数的,再到万能参数
最简单的装饰器:
1 import time 2 # print(time.time()) # 获取当前时间 3 # time.sleep(10) # 让程序在执行到这个位置的时候停一会 4 # print('哈哈哈') 5 def timmer(f): #装饰器,实现补充结果的代码 6 start = time.time() 7 f() 8 end = time.time() 9 print(end - start) 10 def func(): #被装饰器,原则是不能改变函数的代码 11 print('老板好') 12 time.sleep(0.01) 13 14 timmer(func)
进阶:不调用装饰器函数,直接调用别装饰器函数,就可以实现计时功能
1 import time 2 def timmer(f): 3 def inner(): #这个是一个闭包函数,因为使用了外部函数的变量 4 start = time.time() 5 f() 6 end = time.time() 7 print(end - start) 8 return inner #此处返回的一定是inner的内存地址,不能加() 9 def func(): 10 print('老板好') 11 time.sleep(0.01) 12 13 func = timmer(func) 14 func() #相当于inner()
语法糖:
1 import time 2 def timmer(f): 3 def inner(): 4 start = time.time() 5 f() 6 end = time.time() 7 print(end - start) 8 return inner 9 @timmer # func = timmer(func) 语法糖 10 def func(): 11 print('老板好') 12 time.sleep(0.01) 13 14 func()
有返回值的被装饰器:接收被装饰器的返回值
import time def timmer(f): #装饰器函数 def inner(): # 闭包函数,由于调用了外部函数的参数f start = time.time() ret = f() #被装饰的函数 end = time.time() print(end-start) return ret return inner #这个地方一定是传函数名,而不是调用 @timmer #语法糖 @装饰器函数名 func = timmer(func) def func(): print('老板好') time.sleep(0.01) return '新年好' # 函数返回值 ret = func() print(ret) #不想修改函数的调用方式,但是还想再原来的函数前后添加功能 # timmer就是一个装饰器函数,只是对一个函数,有一些装饰作用
有一个参数的被装饰器:利用了*args可以接收无数个位置参数
1 import time 2 def timmer(f): #装饰器函数 3 def inner(*args): 4 start = time.time() 5 ret = f(*args) #同样是函数,需要接收多个位置参数 6 end = time.time() 7 print(end-start) 8 return ret 9 return inner 10 11 @timmer 12 def func(a): #带参数的被装饰器函数 13 print('老板好',a) 14 time.sleep(0.01) 15 return '新年好' # 函数返回值 16 17 ret = func('同事们好') 18 print(ret)
万能的装饰器:利用*args,**kwargs
1 import time 2 def timmer(f): 3 def inner(*args,**kwargs): 4 start = time.time() 5 ret = f(*args,**kwargs) 6 end = time.time() 7 print(end-start) 8 return ret 9 return inner 10 11 @timmer 12 def func(a,b): 13 time.sleep(0.01) 14 print('老板好,大家好',a,b) 15 return '新年好' 16 17 @timmer 18 def func1(a): 19 time.sleep(0.01) 20 print('你们好',a) 21 return '北京欢迎你' 22 23 re = func(1,2) 24 print(re) 25 re1 = func1(3) 26 print(re1)
3.装饰器的固定模式
1 def wrapper(f): # 装饰器函数,f是被装饰的函数 2 def inner(*args,**kwargs): 3 '''在装饰器函数之前要做的事情''' 4 ret = f(*args,**kwargs) # 被装饰的函数 5 '''在被装饰器函数之后要做的事情''' 6 return ret 7 return inner 8 @wrapper 9 def func(): 10 print(123) 11 12 ret = func()
4.习题讲解
#写函数,接收n个数字,求和
1 def sun_func(*args): # 接收的是元组 2 totol = 0 3 for i in args: 4 totol += i 5 return totol 6 print(sun_func(1,2,3,8,55,44))
#写函数,检查获取传入列表或元组对象的所有奇数位索引对应的元素,并将作为新列表返回给调
1 def func(l): 2 return l[1::2] # 切片 3 print(func([1,2,3,4,5,6]))
#写函数,判断用户传入的值的长度是否大于5
1 def func(x): 2 return len(x) > 5 # 判断表达式本身就是一个bool表达式 3 print(func('abcd')) #return 与 print 区别是否需要进行后续的操作
#写函数,如果大于2,则保留前两个长度的内容,并将新内容返回给调用者
1 def func(l): 2 return l[0:2] # 有多少就切多少 ,顾头不顾尾 3 print(func([1,2,3,4,5]))
#写函数,用户传入修改的文件名,与要修改的内容,执行函数,完成整个文件的批量修改操作
1 def func(filename,old,new): 2 import os 3 with open(filename,encoding='gbk') as f,open('%s.bak'%filename,'w',encoding='gbk') as f2: 4 for line in f: 5 if old in line: #这个判断是让新的内容代替旧的内容 6 line = line.replace(old,new) 7 #写文件 8 f2.write(line) #把读到的每一行写到另一个新的文件 9 os.remove(filename) 10 os.rename('%s.bak'%filename, filename) 11 func('F:\hello.txt','小花','小美')
5.小知识点
编程原则:开放封闭原则
开放:对扩展是开放的
封闭:对修改是封闭的
type(),判断函数的类型
浙公网安备 33010602011771号