函数装饰器的独特之处解读

1.开放封闭性

1.开放封闭性从某种意义上促发了装饰器的产生。

"""
1.不能修改被装饰的对象的源代码
2.不能更改被修饰对象的调用方式,且能达到增加功能的效果

"""
例如:

# 1.0版本
def fn():
    print('fn run')


# 2.0版本
def fn():
    print('fn run0')
    print('fn run1')
    print('fn run2')
 fn()

# 修改了源代码,没有更改调用方式,对外电泳方式还是原来的,但功能要有所增加(开放)
# def fn():
#     print('fn run0')
#     print('fn run')
#     print('fn run0')
# fn()

# 更改了调用方式,没有修改原功能代码(封闭)
def wrap(fn):
    print('fn run0')
    fn()
    print('fn run2')
wrap(fn)

2.装饰器

1.什么是装饰器和使用装饰器的好处:

"""
装饰器:就是闭包(闭包场景的一个应用)
        把要装饰的函数作为外层函数的参数通过闭包操作后返回一个替代版函数
优点:
        丰富了原有函数的功能
        提高了程序的拓展性
"""

2.案例:

def vase():
    print('插花')


# vase()

# 修改了函数的源代码
def vase():
    print('插花')
    print('绘画:进行观赏')


# vase()

# 修改了函数的调用方式
def wrap(fn):
    vase()
    print('绘画:进行观赏')


wrap(vase)


def fn():
    vase()
    print('绘画:进行观赏')


vase = fn
vase()


# 函数嵌套结构就是装饰器
def fnr(tag):
    def fb():
        tag()
        print('绘画:进行星尚')

    return fb  # 拓展功能后的vase


vase = fnr(vase)

vase()  # 功能添加了,但是它的调用方式

3.为什么要使用装饰器

    基于第一点的开放封闭性原则,开放封闭原则是我们在开发过程中必须要遵守的一个原则。开放封闭指的是对修改封闭,对扩展开放。在以后写代码时,需要对一个函数什么的添加一个新功能时,切记不能修改它的源代码和它的调用方式。装饰器便是完完全全依照了这个原则,我们添加功能也可以使用装饰器。

既然装饰器遵循开放封闭原则,那么我们便要记住在定义装饰器的时候我们必须遵守装饰器的实现原则:1.不能修改被装饰对象的源代码  2.不能修改被装饰对象的调用方式。

4.装饰器的简单模板

def outer(fn):
    def inner(*args,**kwargs):
        result = fn(*args,**kwargs)
        rerurn result
    return inner
function = outer(fn) # 相当于返回了inner函数

function()

5.装饰器语法糖和他的代码优化

# 比如:我要在插花的基础上,在进行赏花的操作
def outer(fn):
    def inner():
        fn()
        print("绘画:进行观赏")
    return inner

def wrap(fn):
    def inner():
        fn()
        print('摆放功能')
    return inner

# 语法糖 | 笑笑语法
@wrap
@outer  # <==> vase = outer(vase)
def vase():
    print('插花')
# vase = outer(vase)

vase()int('我要插花!')



'''
      总结:一个函数可以被任意一个相关装饰器装饰,也可以被任意几个装饰器装饰
      注:装饰的顺序会影响新增功能的执行顺序
'''

6.运用装饰器实现的登录案例

 

# 需求:如果用户未登录不能看个人中心或者销售,否则可以查看。
is_login = False
def login():
    usr = input('usr:>>>>>')
    if not (len(usr) >= 3 and usr.isalpha()):
        print('验证失败')
        return False
    pwd = input('pwd:>>>>>')
    if usr == 'abcd' and pwd == '123qwe':
        print('登录成功')
        is_login = True
    else:
        print('登录失败')
        is_login = False


def check_login(fn):
    def inner(*args,**kwargs):
        # 查看个人主页,要先登录
        if is_login != True:
            login()

        # 查看个人主页或销售
        result = fn(*args,**kwargs)
        return result
    return inner

@check_login
def home():
    print('个人主页')

@check_login
def sell():
    print('可以销售')

=============================================>>>
输出结果为:登录成功
      个人主页
=============================================>>>

 

posted on 2019-04-02 14:17  程序小王的生命周期  阅读(155)  评论(0编辑  收藏  举报

导航