python装饰器

mac2022-06-30  21

- 装饰器本质

装饰器本质就是一个修饰其他函数的函数,为其他函数添加附加功能

- 装饰器要把握的2个原则

1.不修改被修饰函数的源代码 2.不修改被修饰函数的调用方式

- 装饰器的实现

装饰器 = 高阶函数+函数嵌套+闭包

满足下面任何一个条件都是高阶函数: (1)函数接收的参数是一盒函数名 (2)函数的返回值是一个函数名

函数嵌套:父函数里面还有子函数 闭包:作用域的一种体现,一层套一层(一层一个函数),给最外层传一个参数,可以一直渗透到最里层

只用高阶函数例子:给函数加上统计运行时间的功能 # 方式一:修改了调用方式 import time def foo(): print("你好") def test(func): start_time = time.time() print(func) func() stop_time = time.time() print("函数%s的运行时间为%s;但是函数调用方式从foo()变成了test(foo)" % (func.__name__, stop_time-start_time)) test(foo) # 方式二:虽然没有修改调用方式,但是foo1函数被调用了两次func import time def foo1(): print("你好") def test1(func): start_time = time.time() print(func) func() stop_time = time.time() print("函数%s的运行时间为%s;但是函数调用方式从foo()变成了test(foo)" % (func.__name__, stop_time-start_time)) return func foo1 = test1(foo1) foo1() 高阶函数+函数嵌套实现基本的装饰器架子 # 装饰器架子 def func(): pass def timmer(func): def wrapper(): # 函数执行前操作 func() # 函数执行后操作 return wrapper func = timmer(func) func() 高阶函数+函数嵌套实现基本的装饰器:给函数加上统计运行时间的功能 import time def func(): print("in func") time.sleep(2) def timmer(func): def wrapper(): start_time = time.time() func() stop_time = time.time() print("函数%s的运行时间为%s;但是函数调用方式从foo()变成了test(foo)" % (func.__name__, stop_time-start_time)) return wrapper func = timmer(func) # 这一句等价于在func定义上面加上@time func()

- 装饰器优化:带参数和返回值的装饰器

''' func = timmer(func) func(1,2,3) func=timmer(func)的返回值是wrapper函数,给func加参数等价于给wrapper加参数 所以func(*args, **kwargs) => wrapper(*args, **kwargs) func的返回值要在wrapper中接收一下,再return回去 ''' def timmer(func): # 函数嵌套 def wrapper(*args, **kwargs): start_time = time.time() print(func) res = func(*args, **kwargs) # 参数+返回值 stop_time = time.time() print("%s函数运行时间为%s" % (func.__name__, stop_time-start_time)) return res return wrapper # 高阶函数 def func(*args, **kwargs): time.sleep(1) print(args, kwargs) print("in func") func = timmer(func) res = func(1,2,3) print(res)

- 修改成@的方式

def timmer(func): # 函数嵌套 def wrapper(*args, **kwargs): start_time = time.time() res = func(*args, **kwargs) stop_time = time.time() duration = stop_time-start_time print("%s函数运行时间为%s" % (func.__name__, duration)) return res return wrapper # 高阶函数 @timmer # 等价于 func = timmer(func) def func(*args, **kwargs): time.sleep(1) print("in func") print(args, kwargs) return (args, kwargs) print(func(1, 2, 3))

- 带参数的装饰器–实现认证类型选择

def auth(auth_type="file_auth"): def dec_auth(func): def wrapper(*args, **kwargs): # 验证功能 print("你输入的认证类型是%s" % auth_type) username = input("用户名:").strip() passwd = input("密码:").strip() if username == "root" and passwd == "123": res = func(*args, **kwargs) return res else: print("用户名密码错误") return wrapper return dec_auth # 下面的过程分以下步骤 # (1) auth(auth_type="db_auth")=>dec_auth # (2)@auth(auth_type="db_auth") ==》 car = auth(auth_type="db_auth")=dec_auth(car) @auth(auth_type="db_auth") def car(name): print("欢迎来到%s的购物车"%name) car("ybp")
最新回复(0)