zoukankan      html  css  js  c++  java
  • Py修行路 python基础 (十)装饰器

    装饰器

    一、定义

        装饰器:顾名思义,就是对某个东西起到装饰修饰的功能。

    python中的装饰器,其本质上就是一个python函数,它可以让其他函数不需要任何代码变动的前提下增加额外功能。通俗理解就是 函数 闭包 的实用。

    二、语法及注意事项

      1、书写规范 @ *** ***指装饰器的函数名

      2、装饰器作为一个函数,他会把其下一行的主函数名作为变量,传递到自己的函数去调用。再重新赋值主函数。

      3、装饰器必须放到被装饰的函数上边,并且独占一行;多个装饰器下 ,按照先下后上执行。

    三、为什么要用装饰器?

    开放封闭原则

    源代码上线之后,主函数的定义和调用方式尽量避免更改。装饰器本身在源代码中就是可调用的对象。

    四、装饰器使用举例

    原函数如下:

    1 import time
    2 def index():
    3     time.sleep(3)
    4     print("welcome to oldboy")
    5 index()

    执行结果:

    welcome to oldboy

    在原函数不被更改的情况下,增加新的功能:计算主函数执行的时间!

    1、最原始的无参装饰器(无位置参数)。

     1 import time
     2 
     3 def timer(func):
     4     def wrapper():
     5         start_time=time.time()
     6         func()
     7         stop_time = time.time()
     8         print("running time:%s"%(stop_time-start_time))
     9     return wrapper
    10 @timer
    11 def index():
    12     time.sleep(3)
    13     print("welcome to oldboy")
    14 index()

    执行结果:

    1 welcome to oldboy
    2 running time:3.000171422958374

    2、无参装饰器(有位置参数)

     1 #为定义可以传值的函数,添加计时的装饰器,此时要注意函数和装饰器中的位置参数传值的问题!!!
     2 import time
     3 
     4 def timer(func):
     5     def wrapper(*args,**kwargs):  #有权接管,无权为空!
     6         start_time = time.time()
     7         func(*args,**kwargs)  #home(name)
     8         stop_time = time.time()
     9         print("run time is %s"%(stop_time-start_time))
    10     return wrapper
    11 
    12 @timer   #index = timer(index)
    13 def index():
    14     time.sleep(1.5)
    15     print("welcome to beijing!")
    16 
    17 @timer
    18 def home(name):  #wrapper('alex')
    19     time.sleep(1)
    20     print("welcome to %s home page"%name)
    21 
    22 @timer
    23 def auth(name,passwd):
    24     time.sleep(0.5)
    25     print(name,passwd)
    26 
    27 @timer
    28 def tell():
    29     print("---***---")
    30 
    31 index()
    32 home("alex")
    33 auth("alex","alex3714")
    34 tell()

    执行结果如下:

    1 welcome to beijing!
    2 run time is 1.5000858306884766
    3 welcome to alex home page
    4 run time is 1.0000569820404053
    5 alex alex3714
    6 run time is 0.5010290145874023
    7 ---***---
    8 run time is 0.0

    3、无参装饰器(主函数带有返回值的情况!)

     1 #给带有返回值的函数添加统计时间的装饰器!
     2 
     3 import time
     4 
     5 def timer(func):
     6     def wrapper(*args,**kwargs):
     7         start_time = time.time()
     8         res = func(*args,**kwargs) #my_max(1,2)
     9         stop_time = time.time()
    10         print("run time is %s"%(stop_time-start_time))
    11         return res  #先将所有的功能接收出来,然后在返回
    12     return wrapper
    13 
    14 @timer
    15 def my_max(x,y):
    16     time.sleep(2)
    17     print("max:")
    18     res = x if x>y else y
    19     return res   #函数的返回值!
    20 res = my_max(1,2)   # res = wrapper(1,2)
    21 print(res)

    执行结果如下:

    1 max:
    2 run time is 2.0001144409179688
    3 2

    4、装饰器的实质既然是函数的调用,那么上面介绍完无参的情况,现在举例介绍有参的情况。

    有参装饰器(登陆认证)

     1 #为主函数添加认证功能。主函数不变,在主函数上@*** 一个装饰器,装饰器是靠函数来实现。
     2 #认证功能是在真正的函数调用之前添加上认证的功能,所以认证是在装饰器中添加。
     3 #有参装饰器是在装饰器上添加区分,认证的时候,需要区分不同类型信息的来源(如:本地文件,数据库),
     4 #所以在装饰器上就需要添加认证参数,以区分开认证的来源,执行认证的时候,会在认证主函数中进行逻辑操作。
     5 def auth2(auth_type):  #参数认证函数
     6     def auth(func):
     7         def wrapper(*args,**kwargs):  #认证函数
     8             if auth_type == "file":
     9                 name = input("username:")
    10                 passwd = input("passwd:")
    11                 if name == "song" and passwd =="123":
    12                     print("auth successful")
    13                     res = func(*args,**kwargs)
    14                     return res   #认证成功之后源代码再运行。
    15                 else:
    16                     print("auth error")
    17             elif auth_type == "sql":
    18                 print("不会!")
    19         return wrapper
    20     return auth
    21 
    22 #@auth2(auth_type="sql")    #调用  不同认证类型的参数
    23 #def index():  #index = auth(index)
    24 #    print("welcome to index page")
    25 
    26 @auth2(auth_type="file")  #调用  不同认证类型的参数
    27 def my_index():
    28     print("welcome to inexd page")
    29 #index()
    30 my_index()

    执行结果如下:

    1 username:song
    2 passwd123
    3 auth successful
    4 welcome to inexd page

    5、多个装饰器调用!实现主函数的登录认证功能

     1 #多个装饰器调用!
     2 #1、加上了统计函数的执行时间
     3 #2、加上了认证功能,为避免重复登录认证,执行功能完成之后再判断登录状态。已登录则跳过,第一次登录会有登录信息的认证。
     4 
     5 import time
     6 current_login={'name':None,'login':False}
     7 
     8 def timmer(func):
     9     def wrapper(*args,**kwargs):
    10         start_time=time.time()
    11         res=func(*args,**kwargs)  #my_max(1,2)
    12         stop_time=time.time()
    13         print('run time is %s' %(stop_time-start_time))
    14         return res
    15     return wrapper
    16 
    17 def auth2(auth_type='file'):
    18     def auth(func):
    19         # print(auth_type)
    20         def wrapper(*args,**kwargs):
    21             if current_login['name'] and current_login['login']:
    22                 res=func(*args,**kwargs)
    23                 return res
    24             if auth_type == 'file':
    25                 name=input('username: ')
    26                 password=input('password: ')
    27                 if name == 'zhejiangF4' and password == 'sb945':
    28                     print('auth successfull')
    29                     res=func(*args,**kwargs)
    30                     current_login['name']=name
    31                     current_login['login']=True
    32                     return res
    33                 else:
    34                     print('auth error')
    35             elif auth_type == 'sql':
    36                 print('还他妈不会玩')
    37         return wrapper
    38     return auth
    39 
    40 @timmer
    41 @auth2(auth_type='file') #@auth  #index=auth(index)
    42 def index():
    43     print('welcome to inex page')
    44 
    45 @auth2()
    46 def home():
    47     print('welcome to home page')
    48 
    49 
    50 
    51 #调用阶段
    52 index()
    53 home()
    View Code

    执行结果如下:

    1 username: zhejiangF4
    2 password: sb945
    3 auth successfull
    4 welcome to inex page
    5 run time is 10.760615348815918
    6 welcome to home page
  • 相关阅读:
    fiyocms 2.0.6.1版本漏洞复现及分析
    WPScan使用方法
    sqlmap的使用方法(含靶场)
    COOKIE注入靶场实战
    LDAP注入学习小记
    XSS挑战赛通关
    LANMP安全配置之Nginx安全配置
    LANMP安全配置之MySQL安全配置
    LANMP安全配置之Apache安全配置
    open-source
  • 原文地址:https://www.cnblogs.com/zh605929205/p/6690660.html
Copyright © 2011-2022 走看看