装饰器进阶

Posted wzqwer

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了装饰器进阶相关的知识,希望对你有一定的参考价值。

1. 开放封闭原则

1.对扩展是开放的

    为什么要对扩展开放呢?

    我们说,任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改。所以我们必须允许代码扩展、添加新功能。

  2.对修改是封闭的

    为什么要对修改封闭呢?

    就像我们刚刚提到的,因为我们写的一个函数,很有可能已经交付给其他人使用了,如果这个时候我们对其进行了修改,很有可能影响其他已经在使用该函数的用户。

装饰器完美的遵循了这个开放封闭原则

2.函数中有用信息

导入模块from functools import wraps

print(f1.__doc__) 获取函数说明信息
print(f1.__name__) 获取函数名

def func(*args):
    \'\'\'
    计算两个数的和
    :return:
    \'\'\'
    sum=args[0]+args[1]
    return sum
func(15,17)
print(func.__doc__)      # 计算两个数的和     :return:
print(func.__name__)     #func

结果:

在装饰器中要显示需要添加模块   @wraps(func) #加在最内层函数正上方

from functools import wraps
def wrapper(func):
    @wraps(func)     ##加在最内层函数正上方
    def inner(*args,**kwargs):
        "输出一个数"
        ret=func(*args,**kwargs)
        return ret
    return inner
@wrapper
def func():
    "输出666"
    print(666)
func()
print(func.__doc__)      #输出666
print(func.__name__)     #func

结果:

3. *args **kwargs

*args  **kwargs在执行函数中时是打散,在定义函数,接收时聚合,聚合成元祖.
def func(*args):
    print(args,type(args))    #1 2 3
    print(args,type(args))   #(1, 2, 3) <class \'tuple\'>
func(*[1,2,3])

结果:

  4 .装饰器进阶

flag = True
def wrapper_out(flag):
    def wrapper(func):
        def inner(*args,**kwargs):
            \'\'\'执行函数前\'\'\'
            if flag:
                ret = func(*args,**kwargs)
                \'\'\'执行函数后\'\'\'
                print(222)
                return ret
            else:
                ret = func()
                return ret
        return inner
    return wrapper

@wrapper_out(flag)     #第一步是调用 wrapper_out(flag),接收到返回值wrapper
def func():           #第二步是@wrapper,即func = wrapper(func)
    print(111)
func()

结果:

  2.多个装饰器装饰一个函数

 

def wrapper1(func):  # func = f
def inner1():
print(\'wrapper1 ,before func\')
func()
print(\'wrapper1 ,after func\')
return inner1

def wrapper2(func): # func = inner1
def inner2():
print(\'wrapper2 ,before func\')
func()
print(\'wrapper2 ,after func\')
return inner2

@wrapper2 # f = wrapper2(f) 里面的f == inner1 外面的f = inner2
@wrapper1 # f = wrapper1(f) 返回inner1 f = inner1
def f():
print(\'in f\')
f() # inner2()

结果:

 

以上是关于装饰器进阶的主要内容,如果未能解决你的问题,请参考以下文章

12.前方高能-装饰器进阶

python使用上下文对代码片段进行计时,非装饰器

基础学习之第十二天(装饰器的进阶)

函数进阶(装饰器)

Python进阶第九篇装饰器

测开之函数进阶篇・第七篇《装饰器》