Python函数加工厂-装饰器

Posted

tags:

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

引言:

函数和装饰器好比程序界的加工厂:

1、函数一般可用来加工一种或者多种数据类型的数据:字符串、数字、列表、字典等

举一个简单例子:已知半径求面积

def s(r):
    s = 3.14 * r * r
    return s

调用s函数:输入4,输出半径为4的圆的面积。a相当于面积的容器

a = s(4)
print(a)

2、装饰器是用来装饰函数的函数。其需要输入的原材料为某个函数

以下是装饰器的固定格式:

1 def timer(func):
2     def inner(*args,**kwargs):
3         ‘‘‘执行函数之前要做的‘‘‘
4         re = func(*args,**kwargs)
5         ‘‘‘执行函数之后要做的‘‘‘
6         return re
7     return inner

timer函数是一个进化函数的函数:装饰器

timer是用来加工函数的,即产品应该也应该是函数(进化版)。

def timer(func):
    #
    #func的进化过程
    #
    return inner # 强化变身版func

上面的代码就比较容易理解了,就是定义一个函数去强化函数,得到一个强化func

接下来,我们就深入研究func的强化过程:

1、你return了一个inner函数,他不是凭空产生的,就是石猴还不远万里去学艺,并取了了名字叫孙悟空呢。

所以一开始你要:

def inner(*args,**kwargs):   # inner 今天成立了

我们知道inner是为了强化加工厂func的,所以inner需要的原材料必须是和func一样的。启动万能可变参数(*args,**kwargs)

    def inner(*args,**kwargs):
        ‘‘‘执行函数之前要做的‘‘‘ # 强化1
        re = func(*args,**kwargs)    # 这个是原函数的核心部件,你就不要随便动他了。。。否则,你为啥不自己写一个程序。。。
        ‘‘‘执行函数之后要做的‘‘‘ #强化2
        return re

我们再讲一下为啥要要有  re 这个东西,还要return

因为这就是func原工厂生产的东西啊。。。没有return 你就丢了啊

到了最后变身的 时候了。。。

hahaha之前是一个小小加工厂,注册资金只有10w

后来王思聪老公投资了1亿,hahaha立马走上人生巅峰

inner 是哈哈哈被timer(王思聪)强化后的hahaha 

这时候工商局找来了。。。指着inner说,你不就是原来的hahaha么,必须在我这更改相关信息,但是名字就不能改了

认证:hahaha = timer(hahaha) # 注册资金1亿

后来工商局发现经常性工厂升级,所以后来就直接在营业执照上盖了个戳

@timer

讲了这么多,就是为了加深大家的理解,其实记住下面的就好了

def wrapper(func):

    def inner(*args,**kwargs):#定义函数的时候——*参数的聚合

        ret = func(*args,**kwargs)  #调用函数的时候——*参数的打散

        #func是被装饰的函数,ret是被装饰函数的返回值

        return ret #把被装饰的函数的返回值返回给调用者

    return inner

带参数的装饰器

假如你有成千上万个函数使用了一个装饰器,现在你想把这些装饰器都取消掉,你要怎么做?

def outer(flag):
    def timer(func):
        def inner(*args,**kwargs):
            if flag:
                print(‘‘‘执行函数之前要做的‘‘‘)
            re = func(*args,**kwargs)
            if flag:
                print(‘‘‘执行函数之后要做的‘‘‘)
            return re
        return inner
    return timer

@outer(False)
def func():
    print(111)

func()

多个装饰器装饰同一个函数

def wrapper1(func):
    def inner():
        print(wrapper1 ,before func)
        func()
        print(wrapper1 ,after func)
    return inner

def wrapper2(func):
    def inner():
        print(wrapper2 ,before func)
        func()
        print(wrapper2 ,after func)
    return inner

@wrapper2
@wrapper1
def f():
    print(in f)

f()

附加:关于可变参数的应用

#动态参数
def ccc(*args):#1,2,3,4,5
    print(args)

ccc(1,2,3,4,5)#按位置传参数

t = (1,2,3,4,5)
ccc(t)  ((1, 2, 3, 4, 5),)
ccc(*t)  (1, 2, 3, 4, 5)

def ddd(**kwargs):
    print(kwargs)

# ddd(k = ‘a‘,j = ‘b‘)#按关键字传参数

def eee(*args,**kwargs):
    print(args,kwargs)

# eee(12,123) #先按位置传参,再按关键字传参

def ccc(*args):
    print(ccc:,args)  #(1,2,3,4,5)
    def inner(a,b,c,d,e):
        print(inner,a,b,c,d,e)
    inner(*args)  #*(1,2,3,4,5)  打散

def inner(a,b,c,d,e):
    print(inner,a,b,c,d,e)
# ccc(1,2,3,4,5)
# inner(1,2,3,4,5)

技术分享

 

以上是关于Python函数加工厂-装饰器的主要内容,如果未能解决你的问题,请参考以下文章

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

python装饰器模块

Python深入05 装饰器

如何在 python 中对装饰器工厂输入进行单元测试

Python 参数化装饰器

Python装饰器笔记