Python 装饰器

一、定义

  器即函数

  装饰即修饰,意指为其他函数添加新功能

  装饰器本身可以是任意可调用对象,被装饰的对象本身也可以是任意可调用对象

  实现装饰器:

    装饰器=高阶函数+函数嵌套+闭包

二、原则:

  1 、开放封闭原则:对扩展是开放的,对修改是封闭

  2.1 装饰器的遵循的原则:1 不修改被装饰对象的源代码 2 不修改被调用对象的调用方式

三、目的
  装饰器的目的是:在遵循1和2原则的前提,为其他新功能函数添加

四、定义位置

  @装饰器名,必须写在被装饰对象的正上方,并且是单独一行

import time

def timmer(func):
    # func=index
    def wrapper():
        start=time.time()
        func()
        stop=time.time()
        print('run time is %s' %(stop-start))
    return wrapper


@timmer # index=timmer(index)
def index():
    time.sleep(3)
    print('welcome to index')
@timmer # home=timmer(home)
def home():
    time.sleep(2)
    print('welcome to home page')

index()
home()

 五、带参数的装饰器

无参装饰器版本
current_user={'user':None}
def auth(func):
    def wrapper(*args,**kwargs):
        if current_user['user']:
            return func(*args,**kwargs)

        name=input('name: ').strip()
        password=input('password: ').strip()

        with open('db.txt', encoding='utf-8') as f:
            user_dic = eval(f.read())
        if name in user_dic and password == user_dic[name]:
            res=func(*args,**kwargs)
            current_user['user']=name
            return res
        else:
            print('user or password error')
    return wrapper

@auth #index=auth(index) index=wrapper
def index():
    print('from index')
index()

@auth
def home(name):
    print('welcome %s' %name)

index() #wrapper()
home('egon')
#有参装饰器版本
current_user={'user':None}
def auth(auth_type='file'):
    def deco(func):
        def wrapper(*args, **kwargs):
            if auth_type == 'file':
                if current_user['user']:
                    return func(*args, **kwargs)
                name = input('name: ').strip()
                password = input('password: ').strip()

                with open('db.txt', encoding='utf-8') as f:
                    user_dic = eval(f.read())
                if name in user_dic and password == user_dic[name]:
                    res = func(*args, **kwargs)
                    current_user['user'] = name
                    return res
                else:
                    print('user or password error')
            elif auth_type == 'mysql':
                print('mysql')

            elif auth_type == 'ldap':
                print('ldap')
            else:
                print('not valid auth_type')
        return wrapper
    return deco
@auth(auth_type='mysql') #@deco  #index=deco(index)
def index():
    print('from index')
@auth(auth_type='file')
def home(name):
    print('welcome %s' %name)
index() #wrapper()
home('egon')

 

#带参数的装饰器
import time

def timmer(func):
    #接受的参数
    def wrapper(*args,**kwargs):
        #装饰的功能
        start=time.time()
        #传入要执行的函数
        res=func(*args,**kwargs)

        stop=time.time()
        print('run time is %s' %(stop-start))
        return res
    return wrapper


@timmer # index=timmer(index) #定义装饰器
def index():
    time.sleep(3)
    print('welcome to index')
    return 123

@timmer # home=timmer(home)#定义装饰器
def home(name):
    time.sleep(2)
    print('welcome %s to home page' %name)

# res=index() #res=wrapper()
# print(res)

res1=home('egon') #wrapper('egon')#调用
print(res1)

六、给闭包函数加注释

通过引用from functools import wraps 来进行加入注释说明

import time
from functools import wraps

def timmer(func):
    @wraps(func)
    def wrapper(*args,**kwargs):
        start=time.time()
        res=func(*args,**kwargs)
        stop=time.time()
        print('run time is %s' %(stop-start))
        return res
    return wrapper


@timmer # index=timmer(index)
def index():
    '''这是index函数'''
    time.sleep(3)
    print('welcome to index')
    return 123

print(index.__doc__)
# print(help(index))

 

posted @ 2017-07-23 21:17  刘小伟  阅读(235)  评论(0编辑  收藏  举报