装饰器

一:开放封闭原则

对修改源代码是封闭的,对功能的扩展是开放的。软件一旦上线后,就应该遵循开放封闭原则。即对修改源代码是封闭的,对功能源代码以及调用方式的前提下,为其加上新功能。

总结:

1.不修改源代码

2.不修改调用方式

目的:

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

二:装饰器

什么是装饰器?

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

完整含义:

装饰器即在不修改被装饰对象源代码与调用的前提下,装饰器与被装饰的对象均可以任意可调用的对象。

装饰器----》函数

被装饰器---》函数

三:装饰器的使用

1.无参函数

import time
def index():
    time.sleep(2)
    print('welcome to index page')
def outter(fund):
    def wrapper():
        start_time=time.time()
        fun()
        stop_time=time.time()
        print('stop_time-start_time')
    return wrapper.  (这里函数wrapper不能加括号,加了括号返回值就是None)
index=index(index) (index=wrapper,一个新的index)
index()       ( 相当于wrapper() )

无参函数升级版

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

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

def timmer(func)
    def wrapper(*args,**kwargs):
        start_time=time.time()
        res=func(*args,**kwargs)#调用最原始的home
        stop_time=time.time()
        print(stop_time-start_time)
        return res
     return wrapper
index
=timmer(index) (#新的index=wrapper) home=timmer(home)    (#新的home=wrapper) home(name='egon')   (#新的wrapper=‘name’) index()         (#新的wrapper())

装饰器语法糖

注意点:

@这个符号相当于承上启下的意思

举例:@timmer  timmer这个函数必须上面有,而下面如果是接的函数是index,那么就可以表示为index=timmer(index)。如果下面接的是 home,那就表示为home=timmer(home)

import time
def timmer(func):
    def wrapper(*args,**kwargs):
        start_time=time.time()
        res=func(*args,**kwargs)
        stop_time=time.time()
        print(stop_time-start_time)
        return res
    return wrapper

@timmer       #index=timmer(index)(). (相当于index=wrapper(index)) 
def index():
    time.sleep(1)
    print('welcome to index page')
    return 122

@timmer        #home=timer(home)()。(相当于home=wrapper(home)
def home(name):
    time.sleep(2)
    print('welcome %s to home page'%name)

home('egon')
index()
 

认证装饰器实现

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

def auth(func):
    # func=index
    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 #index=auth(index)( )
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')

叠加多个装饰器

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

def auth(func):
    # func=index
    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

def timmer(func):
    def wrapper(*args,**kwargs):
        start_time=time.time()
        res=func(*args,**kwargs)
        stop_time=time.time()
        print(stop_time-start_time)
        return res
    return wrapper

@timmer # timmer 统计的是auth+index的执行时间
@auth
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()
原文地址:https://www.cnblogs.com/wuchenyu/p/8670915.html