定义:
装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象,实现了软件开发中的一个原则“开放-封闭”原则。
封闭:已实现的功能代码块不应该被修改
开放:对现有功能的扩展开放
1. 本来有一个函数为test,我想在这基础上获取test运行的时间,就可以通过装饰器来实现
def test(): time.sleep(2) print("in the test") 首先创建一个高阶函数,里面再定义一个函数def timmer(func): def warpper(*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 warpper## test = timmer(test) 不会触发函数的执行,只返回函数的函数名warpper## timmer(test)返回的是warpper的内存地址,如果想要在test函数里面传入参数,可以在warpper函数中定义参数 test = timmer(test) ## 这行代码可以简化为在test函数前面@timmer ## 调用函数warpper(),这样就实现了调用方式不变,还能添加额外的功能test()
2. 给网站模块加入自认证
说明:首先网站有三个模块index、home、bbs,index模块不需要认证,home模块类型为local的需要加入自认证,bbs模块类型为ldap需要打印内容,因为多了一层模块下面还有各种类型,所以装饰器里面还需加入一层函数。
def auth(auth_type): print("auth func: ", auth_type) def outer_wrapper(func): def warpper(*args, **kwargs): print("wrapper func args: ", *args, **kwargs) if auth_type == "local": username = input("Username: ").strip() password = input("Password: ").strip() if user == username and passwd == password: print("\033[32;1mUser has passwd authentication\033[0m") res = func(*args, **kwargs) print("--after authentication") return res else: exit("\033[31;1mInvalid username or password\033[0m") elif auth_type == "ldap": print("No need.") return warpper return outer_wrapperdef index(): print("Welcome to index page")@auth(auth_type="local")def home(name): print("%s, welcome to home page" % name) return "from home"@auth(auth_type="ldap")def bbs(): print("Welcome to bbs page")if __name__ == "__main__": user, passwd = "wangzai", "111111" name = "doubi" # index() print(home(name)) # 相当于 # outer_wrapper = auth("local") ## 返回outer_wrapper函数名 # home = outer_wrapper(home) ## 返回wrapper函数名 # print(home(name)) ## 调用warpper函数