所以装饰器最终最完美的定义就是:在不改变原被装饰的函数的源代码以及调用方式下,为其添加额外的功能。
装饰器就是一个函数
范例
def inex(): time.sleep(2) print("欢迎....") def func(x): def func2(): start_time = time.time() x() #由于传入的实参是index 所以这里是index();下相当于闭包 x是自由变量 end_time = time.time() print(end_time - start_time) return func2 index = func(inex) #代码走到这里会执行 func(index);将index做为实参传给func(x)->func(index);执行完return func2(这个func2也就是里边嵌套的函数) index() #这个也就是执行func2那个函数 >>> 欢迎.... 2.00072979927063
#定义一个装饰器的函数 def func1(func_name): def func2(): start_time = time.time() func_name() end_time = time.time() print(end_time - start_time) return func2 @func1 #装饰器中的语法糖;这里等用于 index = func1(index);注意此处@func1和下面的def index是结合的 def index(): time.sleep(1) print("欢迎") return 666 index() @func1 #每次需要调用装饰器的时候 都要在此函数头上加上一个@func1(语法糖) def come(): time.sleep(1) print('login') come()
#带有返回值的装饰器 def func2(x): def func3(): start_time = time.time() ret = x() end_time = time.time() print(end_time - start_time) return ret return func3 @func2 #使用语法糖声明装饰器(与下边的func函数) def func(): time.sleep(0.5) print("欢迎登录博客...") return 666 #此返回值是func函数的返回值 ;重点是”func“这个函数是装饰器里边的 x()所调用的 所以要给x()赋一个值 并return ret = func() print(ret) print(func()) >>> 欢迎登录博客... 0.5008265972137451 666 欢迎登录博客... 0.5003719329833984 666
def func2(x): def func3(name): print(name) start_time = time.time() ret = x(name) end_time = time.time() print(end_time - start_time) return ret return func3 # @func2 #使用语法糖声明装饰器(与下边的func函数) def func(name): time.sleep(0.5) print(f"欢迎登录{name}博客...") return 666 #此返回值是func函数的返回值 ;重点是”func“这个函数是装饰器里边的 x()所调用的 所以要给x()赋一个值 并return ret = func2(func) #执行这部会调用上方的 func2函数 func2的函数返回值是 func3 所以这时 ret 就等于 func3 ret('liu') #执行到这 会调用上方的 fun3函数 并将'liu'传给func3(name)位置参数 再将name传给x(name->'liu') #加上语法糖 def func2(x): def func3(name): print(name) start_time = time.time() ret = x(name) end_time = time.time() print(end_time - start_time) return ret return func3 @func2 #使用语法糖声明装饰器(与下边的func函数) def func(name): time.sleep(0.5) print(f"欢迎登录{name}博客...") return 666 #此返回值是func函数的返回值 ;重点是”func“这个函数是装饰器里边的 x()所调用的 所以要给x()赋一个值 并return func('liu') >>> liu 欢迎登录liu博客... 0.5000627040863037
def func2(x): def func3(*args,**kwargs):#函数的定义 函数的聚合 * args start_time = time.time() ret = x(*args,**kwargs) #函数的执行 * 打散:x(*args) -->x(*(‘liu’,22)) --> x(‘liu’,22) end_time = time.time() print(end_time - start_time) return ret return func3 @func2 #使用语法糖声明装饰器(与下边的func函数) def func(name,age,hobby='运动'): time.sleep(0.5) print(f"欢迎登录{name}{age}岁博客爱好{hobby}...") return 666 #此返回值是func函数的返回值 ;重点是”func“这个函数是装饰器里边的 x()所调用的 所以要给x()赋一个值 并return func('liu',10,hobby='python') # ret = func2(func) #执行这部会调用上方的 func2函数 func2的函数返回值是 func3 所以这时 ret 就等于 func3 # ret('liu') #执行到这 会调用上方的 fun3函数 并将'liu'传给func3(name)位置参数 再将name传给x(name->'liu') @func2 def blog(name,age): print(f'欢迎使用{name},{age}岁的日志功能...') blog('Liu',15) def func2(x): def func3(*args,**kwargs): for i in args: print(i) for k, v in kwargs.items(): print(k, v) start_time = time.time() ret = x(*args,**kwargs) end_time = time.time() print(end_time - start_time) return ret return func3 @func2 #使用语法糖声明装饰器(与下边的func函数) def func(name,age,hobby='运动'): time.sleep(0.5) print(f"欢迎登录{name}{age}岁博客爱好{hobby}...") return 666 #此返回值是func函数的返回值 ;重点是”func“这个函数是装饰器里边的 x()所调用的 所以要给x()赋一个值 并return func('liux',10,hobby='python') # ret = func2(func) #执行这部会调用上方的 func2函数 func2的函数返回值是 func3 所以这时 ret 就等于 func3 # ret('liu') #执行到这 会调用上方的 fun3函数 并将'liux'传给func3(name)位置参数 再将name传给x(name->'liux') @func2 def blog(name,age): print(f'欢迎使用{name},{age}岁的日志功能...') blog('Liu',15)
def wrapper(f): def inner(*args,**kwargs): ''' 添加额外的功能:执行被装饰函数之前的操作 ''' ret = f(*args,**kwargs) ''' 添加额外的功能:执行被装饰函数之后的操作''' return ret return inner
实现基于用户登录成功以后才能执行 comment() darit() 函数
user_info = {} def register(): user = input('请输入注册的用户:') passwd = input('请输入注册的密码:') user_info[user] = passwd def login(): count = 1 while count < 4: username = input('请输入您的用户名:') userpasswd = input('请输入您的密码:') if username not in user_info.keys(): print('sorry,您的用户不存在需要注册~') register() elif username in user_info.keys() and userpasswd == user_info.get(username): print('登录成功') return 1 else: print('sorry 输入有误') count += 1 dic = {'status':0} def wrapper(f): def inner(*args,**kwargs): if dic.get('status') == 1: ret = f(*args, **kwargs) else: login_ret = login() if login_ret == 1: dic['status'] =1 ret = f(*args, **kwargs) return inner @wrapper def comment(): print('欢迎访问评论页面.') comment() @wrapper def darit(): print('欢迎访问日记页面') darit()
def timmer(*args,**kwargs): c = args dct = kwargs def tim(func): def time(*args,**kwargs): print('start...') res = func(*args,**kwargs) print('end...') print(c,dct) # print(name) return res return time return tim @timmer('liu',18,name='liu') #f1=f(f1) def f1(x,y,z): print(f'from f1...{x} {y} {z}') @timmer def f2(x,y,z): print(f'from f1...{x} {y} {z}') return 123 f1(1,2,3)