python学习5_装饰器

装饰器需要掌握以下知识点:

1.为被装饰对象提供新功能的工具

2.装饰器本身、被装饰对象可以是任意可调用对象

3.软件一旦上线后,应该对修改封闭,对扩展开放

4.原则:

  • 不修改被装饰对象的源代码
  • 不修改被装饰对象的调用方式
5.示例代码1无参装饰器:用装饰器(outter)实现统计一个函数(inner)的执行时间
#示例代码1
import time


# 装饰器
def outter(func):

    def wrapper(*args, **kwargs):
        start_time = time.time()
        res = func(*args, **kwargs)
        end_time = time.time()
        print('run time is %s' % (end_time - start_time))
        return res
    return wrapper


# 被装饰函数
@outter # inner = outter(inner)
def inner():
    print("This is inner.")
    time.sleep(3)


@outter # home = outter(home)
def home(name):
    print('welcome %s' %name)
    time.sleep(2)
    return 123


inner()
print('-----')
home('cooky')

 6.示例代码2:装饰器模板

#示例代码2
def outter(func):
    def inner(*args, **kwargs):
        res = func(*args, **kwargs)
        return res
    return inner

7.示例代码3无参装饰器:模拟实现用户验证

#示例代码3
import time
current_userinfo = {'user':None}


def outter(func):
    def wrapper(*args, **kwargs):
        if current_userinfo['user']:
            return func(*args, **kwargs)
        user = input('please input your username:').strip()
        pwd = input('please input your password:').strip()
        if (user == 'cooky' and pwd == '123'):
            print('login successfully')
            current_userinfo['user'] = user
            res = func(*args, **kwargs)
            return res
        else:
            print('login failed')
    return wrapper


@outter
def inner():
    print("This is inner.")
    time.sleep(3)


@outter
def home(name):
    print('welcome %s' %name)
    time.sleep(2)
    return

inner()
home('cooky')

8.示例代码4:多个装饰器的执行顺序:语法自下而上解析,执行过程为从上到下。记住结论为自上而下执行代码就可以了

@outter1
@outter2
def index():
    print('this is index')
#示例代码4
def outter1(func):
    print('2.this is outter1')

    def wrapper1(*args, **kwargs):
        print('3.this is wrapper1')
        res = func(*args, **kwargs)
        return res
    return wrapper1


def outter2(func):
    print('1.this is outter2')

    def wrapper2(*args, **kwargs):
        print('4.this is wrapper2')
        res = func(*args, **kwargs)
        return res
    return wrapper2


@outter1
@outter2
def index():
    print('5.this is index')


index()

9.示例代码5:有参装饰器

#示例代码5
import time

current_userinfo={'user':None}

def auth(engine = 'file'):
    def outter(func):
        def wrapper2(*args, **kwargs):
            if engine == 'file':
                if current_userinfo['user']:
                    return func(*args, **kwargs)
                user = input('please input your username:').strip()
                pwd = input('please input your password:').strip()
                if (user == 'cooky' and pwd == '123'):
                    print('login successfully')
                    current_userinfo['user'] = user
                    res = func(*args, **kwargs)
                    return res
                else:
                    print('login failed')
                elif engine == 'mysql':
                    print('mysql认证机制')
                elif engine == 'ldap':
                    print('ldap的认证机制')
                else:
                    print('不支持改engine')
            return wrapper2
    return outter


@auth(engine = 'ldap')
def index():
    print('welcome to index page')
    time.sleep(3)

index()

10.示例代码6:wraps装饰器实现原始函数的文档和装饰后函数的文档一致

#示例代码6
from functools import wraps

def outter(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        res = func(*args, **kwargs)
        return res
    return wrapper


@outter
def inner():
    """
    this is inner's document
    :return:
    """
    print('this is inner')


print(help(inner))
print(inner.__name__)

猜你喜欢

转载自www.cnblogs.com/cooky/p/9363127.html
今日推荐