Python之第二十天的努力--装饰器2

装饰器2

  • 装饰器:装饰,装修

    增加新的功能

  • 开放封闭原则:

    开放:对代码的拓展封闭。

    封闭:对源码的修改是封闭的。

  • 装饰器:完全遵循开放封闭原则。

  • 装饰器:在不改变原函数的代码以及调用方式的前提下,为其增加新的功能。

  • 装饰器就是一个函数

  • 装饰器的本质就是闭包。

# 版本四:Python做了一个优化;提出了一个语法糖的概念。标准版装饰器。
import time
def timmer(f):
    def inner():
        start_time = time.time()
        f()                     # index()
        end_time = time.time()
        print(f'测试本函数的执行效率:{end_time - start_time}')
    return inner

@timmer         # index = timmer(index)
def index():
    '''有很多代码.....'''
    time.sleep(2)
    print('欢迎登陆博客园首页')


@timmer
def dariy():
    '''有很多代码.....'''
    time.sleep(2)
    print('欢迎登陆博客园日记页面')

# index = timmer(index)       # 每次都得写这句话
index()

# dariy = timmer(dariy)
dariy()

被装饰函数有返回值:

# 版本五:被装饰函数有返回值。
import time
def timmer(f):
    def inner():
        start_time = time.time()
        # print(f'这个是f():{f()}!!!')                     # index()
        r = f()
        end_time = time.time()
        print(f'测试本函数的执行效率:{end_time - start_time}')
        return r
    return inner

@timmer         # index = timmer(index)
def index():
    '''有很多代码.....'''
    time.sleep(2)
    print('欢迎登陆博客园首页')
    return 666

# 加上装饰器不应该改变原函数的返回值,所以666  应该返回给我下面的ret,
# 但是下面的ret实际接收的是inner函数的返回值,而666返回给的是装饰器里面的
# f() 也就是 r   我们现在要解决的问题就是讲r给inner的返回值。
ret = index()       # inner()
print(ret)

被装饰函数有参数:

# 版本六:被装饰函数带参数
import time
def timmer(f):
    def inner(*args,**kwargs):
        # 函数的定义:* 代表聚合   args = ('ww',18)
        start_time = time.time()
        f(*args,**kwargs)                     # index()
        # 函数的执行:* 代表打散   f(*iterable) ---> f(*('ww',18)) ---> f('ww',18)
        end_time = time.time()
        print(f'测试本函数的执行效率:{end_time - start_time}')
    return inner

@timmer         # index = timmer(index)
def index(name):
    '''有很多代码.....'''
    time.sleep(2)
    print(f'欢迎{name}登陆博客园首页')

@timmer
def dariy(name,age):
    '''有很多代码.....'''
    time.sleep(2)
    print(f'欢迎{age}岁的{name}登陆博客园日记页面')

index('kkk')        # inner()
dariy('ww',18)

标准装饰器:

# 标准版的装饰器

def wrapper(f):
    def inner(*args,**kwargs):
        '''添加额外功能:执行被装饰函数之前的操作'''
        ret = f(*args,**kwargs)
        '''添加额外功能:执行被装饰函数之后的操作'''
        return ret
    return inner

装饰器的应用:模拟博客园登录

# 装饰器的应用:登录认证
# 模拟博客园登录

def get_user_pwd():
    user_dict = {}
    with open('register', encoding='utf-8') as f:
        for line in f:
            line_list = line.strip().split('|')
            user_dict[line_list[0].strip()] = line_list[1].strip()
    return user_dict

def login():
    u_dict = get_user_pwd()
    count = 1
    while count < 4:
        username = input('请输入用户名:').strip()
        password = input('请输入密码:').strip()
        if username in u_dict and password == u_dict[username]:
            print('登录成功')
            status_dict['username'] = username
            status_dict['status'] = True
            return True
        else:
            print('用户名密码错误。请重新登录')
        count += 1
    return False

def register():
    print('请完成注册功能')



status_dict = {
    'username' : None,
    'status' : False,
}

def auth(f):
    '''
    你的装饰器完成:访问被装饰函数之前,做一步操作。
    登录成功:让其访问被装饰的函数,登录没有成功,不让访问。

    '''
    def inner(*args, **kwargs):
        if status_dict['status']:

            ret = f(*args, **kwargs)

            return ret
        else:
            if login():
                ret = f(*args, **kwargs)

                return ret


    return inner

@auth
def article():
    print('欢迎访问文章页面')

@auth
def comment():
    print('欢迎访问评论页面')

@auth
def dariy():
    print('欢迎访问日记页面')


article()
comment()
dariy()

你可能感兴趣的:(Python之第二十天的努力--装饰器2)