在说装饰器前,先说一个东西,再Python里,有一个 一切皆对象,一切皆变量。
例:
1 def hello(name="sunjinyao"): 2 return "hi " + name 3 print(hello()) 4 # 输出: 'hi sunjinyao' 5 # 我们可以将一个函数赋值给一个变量,比如 6 hi = hello 7 # 我们这里没有在使用小括号,因为我们并不是在调用hello函数 8 # 而是在将它放在greet变量里头。我们尝试运行下这个 9 print(hi()) 10 # 输出: 'hi sunjinyao'
装饰器:就是给其他函数添加新功能。本质也是个函数。
原则:1.不修改被装饰器函数的源代码2.不修改被装饰函数的调用方式
装饰器 = 高阶函数 + 函数嵌套 + 闭包
高阶函数:函数接收的参数是个函数名或者函数的返回是一个函数名
函数嵌套:定义的函数内还有函数,一层套一层
闭包:在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用。这样就构成了一个闭包。
装饰器框架:
1 #例,变量名随需求更改,这里只是例子 2 def login(func):#参数func代表要装饰的函数 3 def inner(*args,**kwargs):#装饰器的参数不固定 4 #在这里添加需要的功能 5 ret = func(*args,**kwargs) 6 #再这里添加需要的功能 7 return ret 8 return inner #没有()没有执行
例:为TEST函数写一个装饰器,统计TEST函数的运行时间
1 #为TEST函数写一个装饰器,统计TEST函数的运行时间 2 import time #导入时间模块 3 def time_1(func):#func = my_test 4 def inner(): 5 start_time = time.time() 6 ret = func() 7 stop_time = time.time() 8 print('函数的运行时间为%s'%(stop_time-start_time)) 9 return ret 10 return inner 11 @time_1 #必须在所装饰的函数前使用。 12 #@time_1 == my_test = time_1(my_test) 13 def my_test(): 14 time.sleep(3) 15 print('test函数运行完毕')
16 return '这个是my_test的执行结果' 17 #my_test = time_1(my_test) 18 #time_1(my_test) 相当inner函数内存地址 因为time1的reture结果是inner 19 print(my_test())#执行了inner函数
练一练:#编写装饰器,为多个函数加上认证功能(用户密码来源于文件),要求登录一次,后续函数无需再输入密码。输入的密码为3次。
例:文件内容
abc,123
def,456
1 login_status = False 2 def login(func): 3 def inner(*args,**kwargs): 4 global login_status 5 if not login_status: 6 count = 0 7 while count < 3: 8 user_name =input('请输入用户名:') 9 pass_word =input('请输入密码:') 10 with open('my_file',encoding='utf8') as passwd_file: 11 for line in passwd_file: 12 login_name,login_pwd = line.strip().split(',') 13 #用,号分割账号密码并赋值,文件末尾都是有换行的,去掉空格(strip在前) 14 if user_name == login_name and pass_word == login_pwd: 15 login_status = True 16 print('登录成功') 17 count += 3 #为了跳出while循环 18 ret = func(*args, **kwargs) 19 return ret#跳出了for循环 20 else: 21 print('登录失败,请重新登录') 22 count += 1 23 break 24 elif login_status:#在上面循环中,把Login_status状态改成 True之后,就不需要再次输入密码 25 ret = func(*args, **kwargs) 26 return ret 27 return inner 28 @login 29 def shopping_web(): 30 return '购物界面' 31 @login 32 def home_web(): 33 return '个人中心' 34 shopping_web() 35 home_web() 36 print(home_web()) 37 print(shopping_web()) 38 print(home_web())