详解Python修饰器(语法糖)

Python的修饰器(decorator)是一个非常强大的功能,一种优秀的设计模式,将重复的内容抽象出来,赋予一个函数其他的功能,但又不去改变函数自身。使得代码极其简洁,易于维护。

为了能够初步了解修饰器的作用,我们先从一个简单的例子开始。

1.simple example

现在有很多个函数,我们需要得到每个函数的运行时间。为了简单描述,我只用一个函数举例子。函数功能很简单

def foo():
    print('hello')

现在想给这个函数计算一下执行时间

def foo():
    t1 = time()
    print('hello')
    t2 = time()
    print(t2-t1)

但这种办法是不是特别笨,假如我现在不想要这个功能了,我还需要注释掉删除一些内容。有没有不修改foo函数,同时能完成计时的功能。
当然有,修饰器就是做这个事情的。

def run_time(func):
    def warp():
        t1 = time()
        func() # 执行函数
        t2 = time()
        print(t2-t1)
    return warp

我们写了一个闭包,run_time接受唯一的参数,这个参数是某个要被修饰的函数对象func,然后warp函数就是要加上修饰内容,并在其中执行这个被修饰的函数。
接下来我们只要这样使用,

foo = run_time(foo)
foo()

用run_time包装的foo就具有计时功能了。但python支持另一种更加简洁的写法。

@run_time
def foo():
    print('hello')

@叫做语法糖,在函数定义前加上@decorator_name, 那么函数foo执行之前会跳到run_time,执行run_time的内容。其中run_time返回的闭包函数,内部也会执行foo的内容。如果不想要这个功能,仅需要注释掉一行就行了。

现在再来看一种复杂一点的情况。如果foo函数有返回值怎么办?

被修饰的函数有返回值

def foo():
    return 666

则只要闭包函数中执行的func也有返回值,则闭包函数需要返回func的返回值。

def run_time(func):
    def warp():
        # do somethings.
        temp = func() # 执行函数  
        return temp # 需要返回func的返回值
    return warp

被修饰函数带参数的情况

def foo(a, b, c):
    return (a,b,c)

则warp函数需要用*args,**kwargs

def run_time(func):
    def warp(*args, **kwargs):
        # do somethings.
        temp = func(*args, **kwargs) # 执行函数
        return temp
    return warp

实验一下

@run_time
def foo(a, b, c):
    return (a,b,c)
print(foo(1,2,3))
# 打印内容如下
# (1, 2, 3)

更复杂的情况

有的时候我们不仅想用修饰器把重复内容抽取出来,还想让同一个修饰器完成不同的功能。那么我们就需要给修饰器加上参数了。
比如我们想让修饰器打印正在运行函数的名称

def decorator_with_param(name): # 修饰器的参数
    def run_time(func): # func为要修饰的函数对象
        def warp(*args, **kwargs):
            # do somethings.
            print(name)
            temp = func(*args, **kwargs) # 执行函数
            return temp
        return warp
    return run_time

@decorator_with_param('foo') # 把函数名传进去
def foo(a, b, c):
    return (a,b,c)

@decorator_with_param('another_foo') # 把函数名传进去
def another_foo(a, b, c):
    return (a,b,c)
    
print(foo(1,2,3))

参考

谈谈python修饰器
官方文档

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值