装饰器

开放封闭原则

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

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

总结

原则如下:

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 =='egon'and 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()

 

posted @ 2018-03-29 16:55  C3的脚印  阅读(117)  评论(0编辑  收藏  举报