1、装饰器
1.1、装饰器定义
装饰器:
定义:本质上是函数,(装饰器的功能:装饰其他函数),就是为其他函数添加附加的功能。原则:
1.不能修改被装饰的函数的源代码
2.不能修改被装饰的函数的调用方式
简单装饰器程序演示:计算test1函数的运行时间import timedef timemer(func): #使用高阶函数定义装饰器 def warpper(*args,**kwargs): #装饰器的函数,函数体为装饰器的功能主体 start_time=time.time() func() #run test1在装饰器的功能主体中调用原函数,实现原函数的功能 stop_time=time.time() print('the func run time is %s' %(stop_time-start_time)) return warpper #返回了warpper的内存地址信息,下次再调用时加上()才会执行warpper函数@timemer #调用装饰器def test1(): time.sleep(3) print("in the test1")test1() #执行主函数执行结果:in the test1the func run time is 3.000171661376953
小结:这里增加了计算函数运行时间的功能,并且不修改原函数的代码,又不影响原来函数的调用方式。
实现装饰器知识储备:
1.函数即"变量"
2.高阶函数
a: 把一个函数名当做实参传给另外一个函数(在不修改被装饰函数源代码的情况下为其添加功能)
b: 返回值中包含函数名(不修改函数的调用方式)3.嵌套函数
高阶函数+嵌套函数==>装饰器
1.2、装饰器传参
import timedef timer(func):---->使用高阶函数定义装饰器 def deco(*args,**kwargs): #为了解决装饰器的通用性,结合非固定参数解决不同函数需要传参的问题 start_time=time.time() func(*args,**kwargs) stop_time=time.time() print("the func run time is %s" %(stop_time-start_time)) return deco #此处返回的值是deco的内存地址@timer #test1=timer(test1),相当于获取了deco的内存地址def test1(): time.sleep(1) print("in the test1")@timer #test2=timer(test2),相当于获取了deco的内存地址def test2(name,age): time.sleep(1) print("in the test2",name,age)#test1=timer(test1)test1()test2("kim",19)执行结果:in the test1the func run time is 1.0000572204589844in the test2 kim 19the func run time is 1.0000572204589844
1.3、程序练习
需求:网站多页面,一个页面代表一个函数,网站谁都可以登录。现在需要在一些页面中增加验证功能登录#!/usr/bin/python# _*_ coding:utf-8 _*_# Aothr: Kimuser, passwd = 'alex', '123'def auth(auth_type): def out_wrapper(func): def wrapper(*args,**kwargs): if auth_type == "local": print("Authing for file") username = input("Login:").strip() password = input("Password:").strip() if username == user and password == passwd: print("You has passed the authentication.") func(*args,**kwargs) else: exit("Your username or password is invalid.") elif auth_type == "ldap": print("Authing for LDAP.") print("You has passed the ldap authentication.") func(*args, **kwargs) return wrapper return out_wrapperdef index(): print("welcome to index page")@auth(auth_type="local")def home(): print("welcome to home page")@auth(auth_type="ldap")def bbs(): print("welcome to bbs page")#index()Page_list = ["index","home","bbs"]for i in Page_list: print(i)choice = input("Please enter the page you want to view:").strip()if choice == "index": index()elif choice == "home": home()elif choice == "bbs": bbs()else: exit("The page you selected does not exist.")