Python函数的装饰器

一、装饰器的介绍

Python中的装饰器是一种特殊的语法,可以在不改变被装饰函数原有代码的基础上,为函数添加新的功能或修改其行为。装饰器本身可以看作是一个返回函数的函数,它的作用是接受一个函数作为参数,然后返回一个新的函数,这个新函数可以执行被装饰函数的原有代码,也可以在执行前后添加新功能。
这里打个比喻:每个人都有的内裤主要功能是用来遮羞,但是到了冬天它没法为我们防风御寒,咋办?我们想到的一个办法就是把内裤改造一下,让它变得更厚更长,这样一来,它不仅有遮羞功能,还能提供保暖,不过有个问题,这个内裤被我们改造成了长裤后,虽然还有遮羞功能,但本质上它不再是一条真正的内裤了。于是聪明的人们发明长裤,在不影响内裤的前提下,直接把长裤套在了内裤外面,这样内裤还是内裤,有了长裤后宝宝再也不冷了。装饰器就像我们这里说的长裤,在不影响内裤作用的前提下,给我们的身子提供了保暖的功效。

二、什么是装饰器

装饰器的作用实际上就是在不改变函数原有代码的情况下,为它添加新的功能。这可以让我们更加灵活地使用函数,并且避免出现重复代码的情况。常见的装饰器功能包括添加日志、缓存计算结果、检查函数参数等。

1.装饰器的实现

函数装饰器分为:无参装饰器和有参装饰两种,二者的实现原理一样,都是’函数嵌套+闭包+函数对象’的组合使用的产物。

如果想为以下函数添加时间统计功能

import time
def index():
	time.sleep(3)
	print('hellow')
	return 10
index() #函数执行步骤

遵循不修改被装饰源代码的情况下,我们想到的是这样的

start_time = time.time()
index() #函数执行步骤
end_time = time.time()
print('函数代码执行时间%s' % (end_time - start_time))

2.简易装饰器

import time
def index():
	time.sleep(3)
	print('hellow')

def outer(func):
	def inner():
		start_time = time.time()
		res = func()
		end_time = time.time()
		print('函数代码执行时间:%s' % (start_time - end_time))
		return res
	return inner

这样我们便可以在不修改被装饰函数源代码和调用方式的前提下为其加上统计时间的功能,只不过需要事先执行一次outer将被装饰的函数传入,返回一个闭包函数inner重新赋值给变量名 /函数名index,如下

index=outer(index)  #得到index=inner,inner携带对外作用域的引用:func=原始的index
index() # 执行的是inner(),在inner的函数体内再执行最原始的index

至此我们便实现了一个无参装饰器timer,可以在不修改被装饰对象index源代码和调用方式的前提下为其加上新功能。

3.装饰器进阶版本(解决参数问题、解决返回值问题)

但我们忽略了若被装饰的函数是一个有参函数,便会抛出异常

def index1(name):
    time.sleep(2)
    print('hellow', name)

index1 = outer(index1)
index1('world')  #TypeError: index1() missing 1 required positional argument: 'name'

之所以会抛出异常,是因为index1(‘world’)调用的其实是inner(‘world’),而函数inner没有参数。inner函数接收的参数其实是给最原始的func用的,为了能满足被装饰函数参数的所有情况,便用上*args+**kwargs组合,于是修正装饰器timer如下

def outer(func):
    def inner(*args, **kwargs):
        start_time = time.time()
        res = func(*args, **kwargs)
        end_time = time.time()
        print('函数代码执行时间:%s' % (end_time - start_time))
        return res

    return inner

二、装饰器固定模板

def outer(func):
	def inner(*args, **kwargs)
		res = func(*args, **kwargs)
		return res
	return inner

三、装饰器语法糖

Python中的装饰器语法糖是使用 @ 符号来应用装饰器的一种简化写法。使用装饰器语法糖可以使代码更加简洁易读。
下面是一个使用装饰器语法糖的示例:

def outer(func):
    def inner(*args, **kwargs):
        start_time = time.time()
        res = func(*args, **kwargs)
        end_time = time.time()
        print('函数代码执行时间:%s' % (end_time - start_time))
        return res

    return inner

@outer
def index():
    time.sleep(3)
    print('hellow')

在上面的代码中,我们使用 @ 符号将outer装饰器应用到index函数上面。这样就相当于执行了以下代码:

def index():
    time.sleep(3)
    print('hellow')

index = outer(index)
最终输出结果与之前相同

装饰器语法糖使得代码更加简洁易读,特别是在应用多个装饰器时,可以避免过多的嵌套,使代码更加易于维护。同时,使用装饰器语法糖还能减少编码量,并提高代码的可读性。

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Python函数装饰器是一种特殊类型的函数,它可以用来修改其他函数的功能。装饰器可以在不修改被装饰函数源代码的情况下,为其添加额外的功能。装饰器本质上是一个返回函数函数,它使用了闭包的概念。 Python提供了@符号作为装饰器的语法糖,使得应用装饰器更加方便。使用装饰器时,可以直接在被装饰函数的定义上方使用@符号加上装饰器函数的名称,就可以将被装饰函数作为参数传递给装饰器函数进行处理。 函数装饰器的应用场景很广泛,它可以用于添加日志记录、性能分析、权限验证、缓存等功能。通过使用装饰器,我们可以将这些功能从原始函数分离出来,提高代码的可读性和可维护性。 以下是一个简单的示例,演示了如何使用函数装饰器: ``` def decorator(func): def wrapper(*args, **kwargs): # 添加额外的功能 print("装饰器添加的功能") # 调用原始函数 return func(*args, **kwargs) return wrapper @decorator def my_function(): print("原始函数") my_function() ``` 在上面的例子,我们定义了一个装饰器函数`decorator`,它接受一个函数作为参数,并返回一个新的函数`wrapper`。在`wrapper`函数,我们可以添加额外的功能,并调用原始函数。通过使用`@decorator`语法,我们将`my_function`函数传递给装饰器进行处理。 当我们调用`my_function()`时,实际上调用的是装饰器返回的`wrapper`函数。在执行`wrapper`函数之前,会先执行装饰器添加的额外功能,然后再调用原始函数。 这就是Python函数装饰器的基本原理和用法。通过使用装饰器,我们可以轻松地修改函数的功能,使代码更加简洁和可重用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值