极简Python--装饰器

装饰器的作用

       当我们需要对已开发上线的程序添加某些功能,不能对程序中函数的源代码进行修改,不能改变程序中函数的调用方式就可以使用装饰器。

        当然在实现一些通用功能如计算函数调用时间,打日志等,就算能改源码,也最好不要直接改函数,最佳实践还是要用装饰器来实现,对Java熟悉的同学可能已经看出来了,装饰器类似于Java中的AOP(面向切面编程).

高阶函数与闭包

要理解装饰器首先要理解高阶函数胡和闭包的概念,熟悉JavaScript的同学应该对这些概念很熟悉。

在Python中,函数是一等公民,既可以作为参数,又可以作为返回值,当一个函数接收函数作为参数或者返回一个函数,只要满足其中一个条件就可以称为高阶函数

下面代码中pow_2就是一个高阶函数,该函数没啥额外功能,仅演示下

def square(x):
    return x**2

def pow_2(fun):
    return fun

f = pow_2(square)
f(8)

闭包:延伸了作用域的函数

如果一个函数定义在另一个函数的作用域内,并且引用了外层函数的变量,则该函数称为闭包

闭包是由函数及其相关的引用环境组合而成的实体(即:闭包=函数+引用环境)

如下代码所示,inner函数就是一个闭包,它可以使用outer函数的环境,也就是他的变量

def outer():
    x = 1
    z = 10
    
    def inner():
        y = x+100
        return y, z
        
    return inner


f = outer()                # 实际上f包含了inner函数本身+outer函数的环境
print(f)

装饰器的实现

现在实现一个简单的装饰器,计算方法的执行时间

import time

def timer(func):
    def inner():
        print('我是装饰器,开始计时')
        start = time.time()
        func()
        end = time.time()
        print('方法: {}, 共执行了 {:.2f}秒'.format(func.__name__, end-start))
        
    return inner
def f1():
    print('我是f1,我在执行任务。。。')
    time.sleep(1)

f1 = timer(f1)
f1()

f1是目标方法,timer是修饰方法,里面定义了inner并返回该方法。inner里面定义了输出执行时间的逻辑,并执行了f1方法

f1 = timer(f1)表示f1经过了timer的修饰,后面真正执行的是inner方法

装饰器语法糖

在被修饰的方法前写@修饰器方法名

import time

def timer(func):
    def inner():
        print('我是装饰器,开始计时')
        start = time.time()
        func()
        end = time.time()
        print('方法: {}, 共执行了 {:.2f}秒'.format(func.__name__, end-start))
        
    return inner

@timer
def f1():
    print('我是f1,我在执行任务。。。')
    time.sleep(1)

f1()

考虑参数和返回值的情况,完全体装饰器代码如下

import time

def timer(func):
    def inner(*args, **kwargs):
        print('我是装饰器,开始计时')
        start = time.time()
        res = func(*args, **kwargs)
        end = time.time()
        print('方法: {}, 共执行了 {:.2f}秒'.format(func.__name__, end-start))
        return res
        
    return inner

@timer
def f1(sleep):
    print('我是f1,我在执行任务。。。')
    time.sleep(sleep)
    return sleep

print(f1(2))

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值