装饰器

装饰器不能修改被装饰的函数的源代码和调式方法,从而起到装饰这个函数的作用。

比如,有一个函数,在不修改它的情况下得到它的运行时间。

#-*- coding:utf-8 -*-

'''
@auther: Starry
@file: decorator1.py
@time: 2018/1/18 23:11
'''

import time

def timer(func):
    def deco():
        start_time = time.time()
        func()
        end_time = time.time()
        print('the func run time is %s'%(end_time - start_time))
    return deco
@timer  #test1 = timer(test1)
def test1():
    time.sleep(3)
    print('in the test1!')

test1()

  

使用装饰器 timer 来装饰test1函数。从而得到它的运行时间。

上面只是简单的装饰,当被装饰的函数有参数时该怎么办呢?

在装饰器函数timer里,就需要把参数传进去了。

#-*- coding:utf-8 -*-

'''
@auther: Starry
@file: decorator2.py
@time: 2018/1/18 23:31
'''

import time

def timer(func):
    def deco(*args,**kwargs):
        start_time = time.time()
        func(*args,**kwargs)
        end_time = time.time()
        print('the func run time is %s'%(end_time - start_time))
    return deco
@timer
def test2(name):
    print("name:"+name)
test2('Starry')

  

被装饰的函数有参数解决了,但又有一种情况了,当调用装饰器timer去装饰某个函数时,如果装饰器也有参数呢?  比如

@auth(auth_type='local')
@auth(auth_type='ldap')

使用不同的参数来使的调用的方式不同,这使用在装饰器里可以通过加一层函数来解决。

#-*- coding:utf-8 -*-

'''
@auther: Starry
@file: decorator3.py
@time: 2018/1/18 23:33
'''

username, password = 'starry','sky'

def auth(auth_type):
    print('auth func:',auth_type)
    def wrapper(func):
        def deco(*args, **kwargs):
            print('wrapper func:', *args, **kwargs)
            if auth_type == 'local':
                user = input('please input your username:')
                passwd = input('please input your password:')
                if user == username and password == passwd:
                    print('33[32;1mUser has passed authentication33[0m')
                    return func(*args, **kwargs)
                else:
                    print('33[31;1mInvalid username or password33[0m')
            elif auth_type == 'ldap':
                print('服务器端验证')
        return deco
    return wrapper
def index():
    print('welcome to index page')
@auth(auth_type='local')
def home():
    print('welcome to home page')
    return 'from home'
@auth(auth_type='ldap')
def bbs():
    print('welcome to bbs page')

index()
print(home())
bbs()

  
函数里嵌套函数,嵌套了两次,第一个函数是把装饰器timer里的参数传进去,第二个函数将被装饰的函数当成参数传入,第三个函数是把被装饰的函数里的参数传入。

装饰器的常见三种使用就是这样了。

原文地址:https://www.cnblogs.com/xingkongyihao/p/8719347.html