自学Python:python中的装饰器

装饰器

装饰器在面向对象(OOP)中也叫装饰模式,是python面向对象中的一种设计模式,装饰器也可以用函数实现,其主要功能是在不改变函数的原有结构下,为该函数增加其他的一些功能,优点是可以实现代码的复用,写好一个装饰器,可以用到多个想使用该装饰器功能的函数上。

装饰器的应用

一个简单的装饰器

def a(func):
	print(1)

	def b(*args, **kwargs):
		print(2)
		func()
		print(3)
		# return func
	return b


@a
def c():
	print(4)


c()

在这里插入图片描述
当程序运行时:先执行@a,得到一个1和函数的对象b,b和b()是不一样的,b只是一个对象,并不会运行,然后当运行到c()的时候,相当于给了b执行的参数,然后我们会执行2,func()得到4,3,到这里程序结束

带参数的装饰器

def a(func):
	print(1)

	# *args将参数打包成tuple传给函数,**kwargs将参数打包成dict传给函数
	def b(*args, **kwargs):
		print(2)
		func(*args, **kwargs)
		print(3)
		# return func
	return b


@a
def c(d, e):
	print(d + e)


c(3, 4)

在这里插入图片描述
这里最后就相当于执行了a(c(d, e))函数,这里的b()就相当于c()。

当装饰器本身需要传入参数

如果装饰器本身需要传入参数,那么就需要编写一个返回装饰器的高阶函数,举个例子:

def a(n, m):
	def decorator(func):
		def wrapper(*args, **kwargs):
			print("%s1" % n)
			func(*args, **kwargs)
			print("%s3" % m)
			return func
		return wrapper
	return decorator


@a('装饰部分', '装饰部分')
def b(d, e):
	print(d + e)


b(3, 4)

在这里插入图片描述
这个装饰器的效果其实是这样的:
b = a(‘装饰部分’, ‘装饰部分’)(b(3, 4))
首先执行a(‘装饰部分’, ‘装饰部分’),返回decorator()函数,参数为b(3, 4)函数,最终返回wrapper函数。

以上两种定义装饰器的方法都没有问题,但是,python中,一切皆对象,函数也是对象,有__name__属性,但是经过装饰器装饰过后,你在去查看被装饰函数的__name__属性的话,发现它的值从原来的’b‘变成了’wrapper‘!!
因为最终返回的函数wrapper他的__name__属性就是wrapper,所以,需要把原始函数的__name__属性的值复制到wrapper()函数中,否则,某些依赖于函数签名的代码执行就会出错。
不需要编写wrapper.__name__ = func.__name__,python中内置了functools.wraps就是干这个事的,所以一个完整的装饰器写法如下:

from functools import wraps

def a(n, m):
	def decorator(func):
		# 将原函数的__name__等属性复制到wrapper()函数中
		@wraps(func)
		def wrapper(*args, **kwargs):
			print('%s1' % n)
			func(*args, **kwargs)
			print('%s3' % m)
			return func
		return wrapper
	return decorator

@a('装饰部分', '装饰部分')
def b(d, e):
	print(d + e)

b(3, 4)
print(b.__name__)

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值