详解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修饰器
官方文档

Python 装饰器是 Python 中的一项高级功能,可用于修改一个函数或类的行为。装饰器就是一个 Python 函数,它可以接受另一个函数作为参数,然后执行某些操作,并返回原始函数的修改版本。这样,我们就可以通过修改函数的行为来扩展其功能,而不必修改函数本身。 Python 装饰器通常用于在函数前后添加一些额外的功能,比如日志记录、缓存功能、类型检查、性能测试等。装饰器本质上是一个 Python 函数,它接受一个函数对象作为参数,并返回一个修改后的函数对象。 Python 装饰器的语法非常简洁,使用 @ 符号紧接着装饰器函数名,将其放在被装饰的函数定义之前即可。例如: ``` @decorator def func(arg1, arg2, ...): pass ``` Python 装饰器的本质是一个闭包函数,它将被修饰函数作为参数传入,并返回一个新的函数对象,这个新的函数对象增加了额外的功能。因为 Python 函数是一等对象,它们可以像普通变量一样作为参数传递,返回值等等。 Python 装饰器可以嵌套使用,在一个函数上同时应用多个装饰器,这样可以实现更复杂的功能。装饰器还支持带参数的语法,这使得装饰器可以对不同的函数进行不同的操作。 总之,Python 装饰器为程序员提供了一个强大的工具来修改 Python 函数和类的行为,使得其具有更高的可重用性和灵活性。在实际的开发工作中,我们可以根据需要编写自己的装饰器,实现更加优美、高效的代码。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值