装饰器

Posted C3的脚印

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了装饰器相关的知识,希望对你有一定的参考价值。

开放封闭原则

软件一旦上线后,就应该遵循开放封闭原则,即对修改源代码是封闭的,对功能的扩展是开放的,也就是说我们必须要找到一种解决方案:

  能够在不修改一个功能源代码以及调用方式的前提下,为其加上新功能。

总结

原则如下:

1、不修改源代码

2、不修改调用方式

目的:

在遵循1和2原则的基础上扩展新功能

装饰器:

器指的是工具,装饰指的是为被装饰对象添加新功能,

完整含义:

装饰器即在不修改被装饰对象源代码与调用方式的前提下, 为被装饰器的对象添加新功能。

装饰器与被装饰的对象均可以是任意可调用的对象

装饰器=======》函数

被装饰的对象=========》》函数

 

 

无参装饰器

import time
def index():
    star_time =time.time()
    time.sleep(1)
    print(welcome to index page)
    stop_time=time.time()
    print(run time is %s %(stop_time-star_time))

index()


#打印结果为

welcome to index page
run time is 1.0006649494171143

 

修订方案一

import time
def index():
    time.sleep(1)
    print(welcome to index page)

def home(name):
    time.sleep(2)
    print(welcome %s to home page %name)

star_time =time.time()
index()
stop_time=time.time()
print(run time is %s%(stop_time-star_time))

star_time=time.time()
home(egon)
stop_time =time.time()
print(run time is %s%(stop_time-star_time))

#打印结果:
welcome to index page
run time is 1.0000946521759033

welcome egon to home page 
run time is 2.0007834434509277


#修改方案一   此种方法麻烦, 每增加一个或更改 都要从新写一个代码。比较麻烦, 不推荐
import time
def index():
    time.sleep(1)
    print(welcome to index page)

def home(name):
    time.sleep(2)
    print(welcom to home page%name)

def wrapper(func):
    star_time=time.time()
    func()
    stop_time =time.time()
    print (run time is %s%(stop_time-star_time))

wrapper(index)


修改方法二: #对于index( )的调用结果 welcome to index page run time
is 1.0006787776947021 虽然实现了index()增加新功能作用但是却更改了调用方式改成了 wrapper(index)所以是不可以的 而对于home(name )这种有参函数却无法修改, 所以这种修改方式也是不可以的

import time def index(): time.sleep(
3) print(welcom to index page) def outter(func): #func=原index def wrapper(): star_time=time.time() func() #原index 即打印welcom to index page stop_time=time.time() print(stop_time-star_time) # 算时间得结果 return wrapper #返回wrapper函数 index=outter(index) index() #针对index做的修改方案

 

无参装饰器升级版

import time
def index():
    time.sleep(1)
    print(welcom to index page)
    return 122
def home(name):
    time.sleep(2)
    print(welcome %s to home page%name)

def timmer(func):   #func=原index   或者func=原home    所以这个func没有被固定死,可以为其赋不同的值
    def wrapper(*args,**kwargs):
        star_time=time.time()
        res=func(*args,**kwargs)
        stop_time=time.time()
        print(stop_time-star_time)
        return res
    return wrapper

index=timmer(index)
home=timmer(home)

index()
home(name=egon)

#打印结果

welcom to index page
1.0009210109710693
welcome egon to home page
2.000316619873047

升级最终版本
针对这种解决方案  就是用闭包函数 并把之前学过的 *args 与**kwargs  应用到此处 ,完美的解决

无参装饰器的模板   重点

def outer(func):
    def inner(*args,**kwargs):
        res=func(*args,**kwargs)
        return res
    return inner

语法糖

放在被装饰函数的正上方, 单独一行,修饰简洁 便于程序员理解,

import time
def timmer(func):
    def wrapper(*args,**kwargs):
        star_time=time.time()
        res=func(*args,**kwargs)
        stop_time=time.time()
        print(stop_time-star_time)
        return res
    return wrapper
@timmer       #语法糖, 表示index =timmer(index)
def index():
    time.sleep(1)
    print(welcom to index page)
    return 122
@timmer        #语法糖  表示 home=timmer(home)
def home(name):
    time.sleep(2)
    print(welcom %s to home page%(name))

index()
home(egon)

认证装饰器

 

import time
current_user={username:None,
              }
def auth(func):
    def wrapper(*args,**kwargs):
        if current_user[username]:
            print(已经登录过了)
            res=func(*args,**kwargs)
            return res

        uname =input(用户名:).strip()
        pwd =input(密码:).strip()
        if uname ==egonand pwd ==123:
            print(登陆成功)
            current_user[username]=uname
            res =func(*args,**kwargs)
            return res
        else:
            print(用户名或密码错误)
    return wrapper
@auth
def index():
    time.sleep(1)
    print(welcome to index page)
    return 122
@auth
def home(name):
    time.sleep(2)
    print(welcome %s to home page %(name))

index()

home(egon)

叠加装饰器

@timmer # timmer 统计的是auth+index的执行时间
@auth
def index():
    time.sleep(1)
    print(welcome to index page)
    return 122

index()

@auth
@timmer  # timmer 统计的是index的执行时间

def index():
    time.sleep(1)
    print(welcome to index page)
    return 122

index()

有参装置器

import time
current_user={
    username:None,
    # login_time:None
}

def auth(engine):
    # engine=file
    def auth2(func):
        # func=index
        def wrapper(*args,**kwargs):
            if engine == file:
                if current_user[username]:
                    print(已经登陆过了)
                    res=func(*args,**kwargs)
                    return res

                uname=input(用户名>>: ).strip()
                pwd=input(密码>>: ).strip()
                if uname == egon and pwd == 123:
                    print(登陆成功)
                    current_user[username]=uname
                    res=func(*args,**kwargs)
                    return res
                else:
                    print(用户名或密码错误)
            elif engine == mysql:
                print(基于MyQL的认证)
            elif engine == ldap:
                print(基于LDAP的认证)
        return wrapper
    return auth2

@auth(ldap) #@auth2 #index=auth2(index) #index=wrapper
def index():
    time.sleep(1)
    print(welcome to index page)
    return 122


index() # wrapper()

 

以上是关于装饰器的主要内容,如果未能解决你的问题,请参考以下文章

Python面向对象学习之八,装饰器

thymeleaf 片段渲染后重新加载 javascript

代码缺乏装饰?使用ts装饰器来装饰你的代码

代码缺乏装饰?使用ts装饰器来装饰你的代码

代码缺乏装饰?使用ts装饰器来装饰你的代码

代码缺乏装饰?使用ts装饰器来装饰你的代码