Python3.7之装饰器

Python3.7之装饰器

1、装饰器的功能

针对软件开发的“开放-封闭”原则,即:python

封闭:已实现的功能代码块不该该被修改闭包

开放:对现有功能的扩展开放函数

所谓的装饰器,就是经过装饰器函数,来修改原函数的一些功能,使得原函数不须要修改。this

2、装饰器引入

1.原有的功能函数以下:

def f1():
    print('f1 called: ')


def f2():
    print('f2 called: ')

2.现须要对两个功能函数进行权限验证,即须要引入一个闭包函数:

def w1(func):
    def inner():
        print('----权限验证----')
        func()

    return inner

review:闭包函数的条件code

① 在一个外函数中定义了一个内函数。开发

② 内函数里运用了外函数的临时变量。class

③ 而且外函数的返回值是内函数的引用。test

3.装饰后的代码:

# 在执行w1函数的时候,此时直接把inner函数返回了,同时把它赋值给f1
# 此时的f1已经不是未加装饰时的f1了,而是指向了w1.inner函数地址
def w1(func):
    def inner():
        print('----权限验证----')
        func()

    return inner

# 当python解释器执行到这句话的时候,会去调用w1函数,同时将被装饰的函数名做为参数传入(此时为f1)
@w1  # f1 = w1(f1)
def f1():
    print('f1 called: ')


@w1
def f2():
    print('f2 called: ')

# 在调用f1()的时候,其实调用的是w1.inner函数
# 那么此时就会先执行权限验证,而后再调用原来的f1(),该处的f1就是经过装饰传进来的参数f1
f1()
f2()

'''
----权限验证----
f1 called: 
----权限验证----
f2 called: 
'''

这样下来,就完成了对f1的装饰,实现了权限验证。变量

3、对有参函数进行装饰

若是原函数有参数,那闭包函数必须保持参数个数一致,而且将参数传递给原方法扩展

1.固定参数:

def w_say(fun):

    def inner(name):  # 此处应有参数
        """
        若是被装饰的函数有形参,那么闭包函数必须有参数
        :param name:
        :return:
        """
        print('say inner called')
        fun(name)  # 将参数传给原方法

    return inner


@w_say
def hello(name):
    print('hello ' + name)


hello('Vivian')
'''
say inner called
hello Vivian
'''

2.非固定参数:

def w_add(func):

    def inner(*args):
        print('add inner called')
        func(*args)

    return inner


@w_add  # 共有装饰器,被装饰的函数的形参不固定
def add(a, b):  # 被装饰的函数有形参
    print('%d + %d = %d' % (a, b, a + b))


@w_add
def add2(a, b, c):
    print('%d + %d + %d = %d' % (a, b, c, a + b + c))


add(2, 4)
add2(2, 4, 6)

'''
add inner called
2 + 4 = 6
add inner called
2 + 4 + 6 = 12
'''

4、对带有返回值的函数进行装饰

def w_test(func):
    def inner():
        print('w_test inner called start')
        # 对test进行调用以后,接收返回值s
        str0 = func()  # 原test的返回值传递给str0
        print('w_test inner called end')
        # 被装饰以后的test返回值为str0
        return str0
    return inner


@w_test  # test = w_test(test)
def test():
    print('this is test fun')
    return 'hello'


ret = test()
print('ret value is %s' % ret)

'''
w_test inner called start
this is test fun
w_test inner called end
ret value is hello
'''

5、带参数的装饰器

相关文章
相关标签/搜索