Python基础 ( 七 ) —— 装饰器
#装饰器
#定义:用于修饰函数的函数(给函数添加新功能)
原则:不改变函数的调用方式
不改变函数源代码
装饰器=高阶函数(函数的参数或返回值为函数) + 函数嵌套 + 闭包
#小补充
1.获取运行时间
import time
start = time.time()
time.sleep(1)
end = time.time()
print(end-start)
2.一种不用索引取列表首位的方法(解压序列)
l=[1,2,3,4,5,6] (a,*_,c)= l #这里的_就是个变量名,用其他字符串也可以 print(c) #输出最后一个数 print(_) #输出去除首尾的中间数
或者可以取任意位置的值
l=[1,2,3,4,5,6] (a,b,*_,c,d)= l print(a,b,c,d) print(_)
3.交换变量的值(简便)
a,b=1,2 a,b=b,a #其实用了元祖的概念做了以下步骤 a,b = (a,b) = b,a print(a)
#装饰器的前身——满足装饰器原则,但多运行了一次原函数
#只使用了高阶函数
import time
def object():
time.sleep(1)
print('对象函数运行成功')
def processor(fuc):
start_time = time.time()
fuc()
end_time = time.time()
print('函数运行时间:%s' %(end_time-start_time))
return fuc
object = processor(object)
object()
#函数嵌套——函数里面定义函数
def father(name): print('from father %s' %name) def son() : #这里的son 为局部变量,函数外部无法单独调用 print('from father %s' %name) print(locals()) father('alex')
#闭包——在每个作用域里封装变量

#装饰器框架
def timmer(func) : def wrapper(): func() return wrapper()
#语法糖(一些python内置的语句,加在定义的函数前,用于修饰接下来定义的函数)
这里简单举例子:
def a(func): print(func()) return func @a # 做了以下处理 : b=a(b) def b(): return 'b函数'
#综合以上,我们就可以做一个简单装饰器(以计时器为例)
import time def timmer(func): def wrapper(): start_time=time.time() res=func() #用于获取返回值 end_time=time.time() print('函数的运行时间为 %s s' %(end_time-start_time)) return res #获取返回值 return wrapper @timmer def function_test(): time.sleep(1) print('函数运行完毕') return '这是返回值' a = function_test() print(a) #输出返回值
#被修饰的函数带有参数该如何处理?
import time def timmer(func): def wrapper(*args,**kwargs): #保证传入的是动态参数,不把参数定死 start_time=time.time() res=func(*args,**kwargs) #同上 end_time=time.time() print('函数的运行时间为 %s s' %(end_time-start_time)) return res return wrapper @timmer def sum1(x,y=1): time.sleep(1) for i in range(1,x+1): y=y*i return y print('阶乘结果为:%s' %(sum1(3)))
#小作业:查找、添加、替换、删除指定格式文本指定内容
#学习用局部变量tag控制逻辑判断的方法
tag = True while tag: print('layer1') choice=input('输入:') if choice == 'quit':break if choice == 'quit_all': tag = False while tag: print('layer2') choice = input('输入:') if choice == 'quit': break if choice == 'quit_all':tag=False while tag: print('layer3') choice = input('输入:') if choice == 'quit': break #不用tag控制的话,需要三次输入quit才能终止循环 if choice == 'quit_all': tag = False #用tag控制一次退出所有循环
#以下为作业
import os def fetch(path,content): #打印第1和第2个含查找内容的行之前的文本 with open(path,'r',encoding='utf8') as f : ret=[] tag=False #利用tag保存状态 name = 'backend %s\n' %content for i in f : if i == name : tag=True continue #查到包含指定字符串的那行不要,跳入下一行 if tag and i.startswith('backend'): tag = False if tag: print(i,end='') ret.append(i) return ret def add(path,content): pass def change(path,data): res = fetch(path,data[0]) if not res or data[1] not in res: print('替换内容不存在') else: with open(path, 'r', encoding='utf8') as f, open('%s1' %path, 'w', encoding='utf8') as f1: tag=False count=False for i in f : if i == ('backend %s\n' %data[0]): res.insert(0,'backend %s\n' %data[0]) tag=True count=True continue if tag and i.startswith('backend'): tag = False if not tag: f1.write(i) if tag: if count: for j in res: if j == data[1]: f1.write(data[2]) else: f1.write(j) count=False os.rename('test','test.bak') os.rename('test1','test') os.remove('test.bak') return '替换完毕' def delete(path,content): pass dic_func={ '1':fetch, '2':add, '3':change, '4':delete } dic_func1={ '1':'查找', '2':'添加', '3':'更改', '4':'替换' } msg='''1:查找\n2:添加\n3:更改\n4:删除\n5:退出 ''' if __name__ == '__main__': #规范:把调用函数的代码写在这个判断语句下面,函数统一写在上方 while True: print(msg) value = input('请选择功能:').strip() if not value :continue if value=='5':break data = input('请输入%s内容:' %dic_func1[value]).strip() path = input('请输入文件路径:').strip() if value == '3': data = eval(data) print(dic_func[value](path,data)) break #3模式下输入的内容格式如下 #['www.oldboy1.org',' server 2.2.2.7 2.2.2.7 weight 30 maxconn 4000\n',' 此处已被修改\n']
#程序的解耦(先这么理解:将函数重复的代码统一管理)
1 import os 2 def handle(path,res=None,x=None,y=None): #把各个函数相同的部分统一写成一个函数 3 if not y: 4 with open(path,'r',encoding='utf8') as f : 5 ret=[] 6 tag=False #利用tag保存状态 7 name = 'backend %s\n' %x 8 for i in f : 9 if i == name : 10 tag=True 11 continue #查到包含指定字符串的那行不要,跳入下一行 12 if tag and i.startswith('backend'): 13 tag = False 14 if tag: 15 print(i,end='') 16 ret.append(i) 17 return ret 18 else: 19 with open(path, 'r', encoding='utf8') as f, open('%s1' % path, 'w', encoding='utf8') as f1: 20 tag = False 21 count = False 22 for i in f: 23 if i == ('backend %s\n' % data[0]): 24 res.insert(0, 'backend %s\n' % data[0]) 25 tag = True 26 count = True 27 continue 28 if tag and i.startswith('backend'): 29 tag = False 30 if not tag: 31 f1.write(i) 32 if tag: 33 if count: 34 for j in res: 35 if j == data[1]: 36 f1.write(data[2]) 37 else: 38 f1.write(j) 39 count = False 40 os.rename('test', 'test.bak') 41 os.rename('test1', 'test') 42 os.remove('test.bak') 43 return '替换完毕' 44 def fetch(path,content): #打印第1和第2个含查找内容的行之前的文本 45 return handle(path,x=content) 46 def add(path,content): 47 pass 48 def change(path,data): 49 res = fetch(path,data[0]) 50 if not res or data[1] not in res: 51 print('替换内容不存在') 52 else: 53 return handle(path,res,x=None,y=data) 54 def delete(path,content): 55 pass 56 dic_func={ 57 '1':fetch, 58 '2':add, 59 '3':change, 60 '4':delete 61 } 62 dic_func1={ 63 '1':'查找', 64 '2':'添加', 65 '3':'更改', 66 '4':'替换' 67 } 68 msg='''1:查找\n2:添加\n3:更改\n4:删除\n5:退出 69 ''' 70 if __name__ == '__main__': #规范:把调用函数的代码写在这个判断语句下面,函数统一写在上方 71 while True: 72 print(msg) 73 value = input('请选择功能:').strip() 74 if not value :continue 75 if value=='5':break 76 data = input('请输入%s内容:' %dic_func1[value]).strip() 77 path = input('请输入文件路径:').strip() 78 if value == '3': 79 data = eval(data) 80 print(dic_func[value](path,data)) 81 break 82 #3模式下输入的内容格式如下 83 #['www.oldboy1.org',' server 2.2.2.7 2.2.2.7 weight 30 maxconn 4000\n',' 此处已被修改\n']

浙公网安备 33010602011771号