python 之装饰器(一)

                                                 python  之装饰器(一)

       装饰器一般在不修改源代码的情况下,给程序增添功能。满足以下几点:

1.不能修改被装饰的函数的源代码

2.不能修改被装饰的函数的调用方式

3. 满足1、2的情况下给程序增添功能

       主要思想: 函数+实参高阶函数+返回值高阶函数+嵌套函数+语法糖 = 装饰器

       函数都比较熟悉,也是一个对象,而且函数对象可以被赋值给变量,通过变量也能调用该函数。下面通过统计test()运行时间的例子说明这几点。

def test():
    time.sleep(2)
    print("deco is running")

1.1 高阶函数

高阶函数:把一个函数名当作实参传给另外一个函数(“实参高阶函数”), 返回值中包含函数名。

看如下的实现:

import time

def test():
    time.sleep(2)
    print("deco is running")

def deco(func):
    start = time.time()
    func()    #2
    stop = time.time()
    print(stop-start)

deco(test)    #1

说明:#1处,test作为参数传递给func,func也指向之前test所定义的那个函数体。deco()内部,func就是test。在#2处,调用函数执行test()。实现计算test()运行时间的功能。

但是:可以看到,修改被装饰函数的调用方式。所以用到另一个概念“嵌套函数”。

1.2 嵌套函数

嵌套函数指的是函数内部定义一个函数,而不是调用。如下:

def func1():
    def func2():   # 嵌套函数
        pass

def func1():
    func2()   #调用函数

为实现上述统计时间的功能,同时满足上面的3点:

import time

def test():
    time.sleep(2)
    print("test is running!")

def timer(func): #5
    def deco():
        start = time.time()
        func()
        stop = time.time()
        print(stop-start)
    return deco


test = timer(test) #6

test()      #7

说明: 在#6处,把test作为参数传递给了timer(),在timer()内部,func = test;定义了一个deco()函数,并未调用,只是在内存中保存且标签为deco。在timer()函数的最后返回deco()的地址deco。然后再把deco赋值给了test,那么此时test已经不是原来的test,也就是test原来的那些函数体的标签换掉了,换成了deco。那么在#7处调用的实际上是deco()。这段代码本质上是修改了调用函数,但在表面上并未修改调用方式,而且实现了附加功能。

 

运行结果:

1.3 语法糖

装饰器在装饰时,需要在每个函数前面加上:

test = timer(test) #6

而Python提供的@timer,就可以实现装饰作用。

以上是无参形式。

 

而针对装饰有参函数,及带参的装饰器后续详细总结。

装饰有参函数:当test(parameter)有参数时,就必须给func()和deco()也加上参数,为了使程序更加有扩展性,因此在装饰器中的deco()和func(),加了可变参数*agrs和 **kwargs。

带参的装饰器:不同的函数有不同的装饰,@decorator(parameter = value),需要把parameter参数传递到装饰器中,再加一层函数来接受参数。

 

参考:https://www.jianshu.com/p/7a77f3f1ebc8

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值