首页 > 其他分享 >装饰器

装饰器

时间:2024-06-15 16:22:54浏览次数:23  
标签:return 函数 inner func print 装饰 def

视频链接:【【专题】彻底学会Python装饰器】https://www.bilibili.com/video/BV1Vv411x7hj?p=2&vd_source=e6865dbe0ecc5ec30951bfda79422846

1、闭包

要想了解装饰器,首先要了解一个概念,闭包。什么是闭包?一句话说就是,在函数中再嵌套一个函数,并且引用外部函数的变量,这就是一个闭包了。下面给出一个闭包的代码:

python复制代码解释def outer(x):
    def inner(y):
        return x + y
    return inner

print(outer(6)(5))
-----------------------------
输出结果:11

如代码所示,在outer函数内,又定义了一个inner函数,并且inner函数又引用了外部函数outer的变量x,这就是一个闭包了。在输出时,outer(6)(5),第一个括号传进去的值返回inner函数,其实就是返回6 + y,所以再传第二个参数进去,就可以得到返回值,6 + 5。

2、装饰器

装饰器就是一个闭包,装饰器是闭包的一种应用。什么是装饰器呢,简言之,python装饰器就是用于拓展原来函数功能的一种函数,这个函数的特殊之处在于它的返回值也是一个函数,使用python装饰器的好处就是在不用更改原函数的代码前提下给函数增加新的功能。使用时,再需要的函数前加上@demo即可。

现在给你一个函数,在不修改源码的情况下。实现在函数执行前和执行后分别输入"before"和"after"。

go复制代码解释def func():
	print("我是func函数")
	va1ue(11,22,33,44)
	return value

result func()
print(result)

2.1、第一次比较

正常实现

go复制代码解释def func():
	print('before') #加上执行前的before

	print("我是func函数")
	va1ue(11,22,33,44)
	return value

	print('after') #加上执行后的after
result func()
print(result)

闭包实现

go复制代码解释def func():
	print("我是func函数")
	va1ue(11,22,33,44)
	return value

def outer(origin):
	def inner():
		print('before') #加上执行前的before
		res = origin() #调用原来的func函数
		print('after') #加上执行后的after
		return res
	return inner

func = outer(func) #此时的func不再是原来的func,而变成了inner函数
result = func()
print(result)

2.2、第二次比较

正常实现方式不变,我们改写闭包实现方式。

Python的语法糖中存在特殊的语法,在某个函数的上方使用:

@函数名 def xxx(): pass python内部会自动执行,函数名(xxx),执行完后,再将结果赋值给xxx。 xxx = 函数名(xxx)

改进闭包实现

python复制代码解释def outer(origin):
	def inner():
		print('before') #加上执行前的before
		res = origin() #调用原来的func函数
		print('after') #加上执行后的after
		return res
	return inner
@outer #func=outer(func)
def func():
	print("我是func函数")
	va1ue(11,22,33,44)
	return value

result = func()
print(result)

2.3、第三次比较

当我存在多个函数时,在不修改源码的情况下。实现在函数执行前和执行后分别输入"before"和"after"。

css复制代码解释def func1():
	print("我是func1函数")
	va1ue(11,22,33,44)
	return value

result func1()
print(result)

def func2():
	print("我是func2函数")
	va1ue(11,22,33,44)
	return value

result func2()
print(result)

def func3():
	print("我是func3函数")
	va1ue(11,22,33,44)
	return value

result=func3()
print(result)

正常实现方式需要对每个函数内部进行修改 闭包实现如下:

python复制代码解释def outer(origin):
	def inner():
		print('before') #加上执行前的before
		res = origin() #调用原来的func函数
		print('after') #加上执行后的after	
		return res
	return inner

@outer
def func1():
	print("我是func1函数")
	va1ue(11,22,33,44)
	return value

@outer
def func2():
	print("我是func2函数")
	va1ue(11,22,33,44)
	return value

@outer
def func3():
	print("我是func3函数")
	va1ue(11,22,33,44)
	return value

func1()
func2()
func3()

因此,我们这里对应用场景做一个简单的总结:如果对与修改的函数比较少,只是需要对函数的前后增加一部分功能,可以直接修改原函数;如果我们需要修改的原函数比较多,我们可以通过装饰器(对函数进行装饰,不改变内部结构)的方式进行增加函数功能。

2.4、装饰器优化支持多个参数

如果原来的函数含有多个参数

python复制代码解释#对于需要装饰的函数含有参数的问题,需要在inner和origin函数后面跟上不定长的参数选项
def outer(origin):
	def inner(*args,**kwargs):
		print('before') #加上执行前的before
		res = origin(*args,**kwargs) #调用原来的func函数
		print('after') #加上执行后的after
		return res
	return inner

@outer
def func1(a1):
	print("我是func1函数")
	va1ue(11,22,33,44)
	return value

@outer
def func2(a1,a2):
	print("我是func2函数")
	va1ue(11,22,33,44)
	return value

@outer
def func3(a1):
	print("我是func3函数")
	va1ue(11,22,33,44)
	return value

func1()
func2()
func3()

3、更深层次的伪造

python复制代码解释def outer(func):
	def inner(*args,**kwargs):
		'''这是inner函数的注释'''
		res = func(*args,**kwargs) #调用原来的func函数
		return res	
	return inner

 @outer
def func():
	'''这是func函数的注释'''
	pass
func()

#在未用装饰器之前
#print(func.__name__) #'func'
#print(func.__doc__) #这是func函数的注释

#在用装饰器之后
print(func.__name__) #'inner'
print(func.__doc__) #这是inner函数的注释

很显然装饰器会改变原来函数,但有些时候我们不需要改变原来函数的注释和名称,我们可以使用python内置的functools模块,具体代码看一看装饰器总结

4、装饰器总结

  • 实现原理:基于@语法和函数闭包,将原函数封装在闭包中,然后将函数赋值为一个新的函数(内层函数),执行函数时再在内层函数中执行闭包中的原函数。
  • 实现效果:可以在不改变原函数内部代码和调用方式的前提下,实现在函数执行和执行扩展功能。
  • 适用场景:多个函数系统统一在执行前后自定义一些功能。
  • 模板代码:
python复制代码解释import functools
def outer(func):
	@functools.wraps(func) #inner.__name__ = func.__name__    inner.__doc__=func.__doc__
	def inner(*args,**kwargs):
		# 执行前
		res = func(*args,**kwargs) #调用原来的func函数
		# 执行后
		return res	
	return inner
 @outer
def func():
	pass
func()

标签:return,函数,inner,func,print,装饰,def
From: https://www.cnblogs.com/yang-shuo/p/18249420

相关文章

  • Day25.密码加密、登录认证装饰器
    1.密码加密、登录认证装饰器_md5加密方法代码 md5加密方法代码:importhashlib#md5加密defget_pwd_md5(password):md5_obj=hashlib.md5()md5_obj.update(password.encode('utf-8'))#密码加盐salt='一二三四五'md5_obj.update(salt.enc......
  • 2024-06-05 拷贝、函数、装饰器、迭代生成器
    一、浅拷贝lists=[1,2,[6]]内存空间不同,浅拷贝内容不变 new_lists=copy(lists)lists.append(7)print(lists,new_lists)//[1,2,[6],7][1,2,[6]]改变列表中内容,内存空间相同,数值改变new_lists=copy(lists)lists[-1].append(7)print(lists,new_lists)//[......
  • python里装饰器的作用是什么
    在Python中,装饰器(decorator)是一种高级函数,用于修改或扩展其他函数或方法的行为,而无需直接修改它们的代码。装饰器常用于以下场景:日志记录:记录函数的调用信息,如函数名、参数和返回值。权限验证:在执行函数前检查用户是否有权限。性能测量:测量函数的执行时间。缓存:缓存函数的返回......
  • [干货][HarmonyOS NEXT]鸿蒙中除了这些还有哪些装饰器呢?
    @Entry:将结构体标记为页面组件,代表一个完整的页面。@Component:将结构体标记为可复用的组件。@Preview:让组件能够在开发过程中进行预览。@State:用于定义组件内部的响应式状态变量需给初始值@Prop:实现父组件到子组件的数据单向传递。可以给初始值也可以不给@Link:达成父组件......
  • 流畅的python--第九章 装饰器和闭包
    装饰器基础知识装饰器是一种可调用对象,其参数是另一个函数(被装饰的函数)。装饰器可能会对被装饰的函数做些处理,然后返回函数,或者把函数替换成另一个函数或可调用对象。假如有一个名为decorate的装饰器:@decoratedeftarget():print("runningtarget()")以下写法与上面的效......
  • 装饰器,测试时间
    装饰器在不改变原来函数的基础上,给函数添加新的功能importtimedefget_data(func):defget_hello(*args,**kwargs):begin_time=time.time()#开始时间data=func()stop_time=time.time()#结束时间print(stop_time-begin_time)returndatareturnget_hello@get_d......
  • 26-unittest之装饰器(@classmethod)
            unittest中的setUp可以在每个测试方法运行前执行,有效的减少了代码量。但有个弊端,比如打开浏览器操作,执行每个测试方法前都要重新打开一次,这样就会浪费很多时间。        是否可以只打开一次浏览器,执行完所有的测试方法后再关闭浏览器呢?这里就需要用到......
  • 多线程、队列、装饰器统计时间
    """一个列表中有100个url地址(每个请求0.5秒),设计一个程序,获取列表的url地址使用5个线程去发送这100个请求,计算出总共请求的时间"""importqueueimporttimefrommultiprocessing.poolimportThreadPooldefdownload(q:queue.Queue):whilenotq.empty():......
  • ts 装饰器测试
    interfacemycbdInterface{alert(name:string):void,one?:string}//函数装饰器constmyconsole:MethodDecorator=(...rest)=>{console.log(rest,"rest")}//类装饰器constmylog2:ClassDecorator=(target)=>{console.log(target,......
  • 23种设计模式之装饰模式
    装饰模式1、定义装饰模式:动态的给一个对象增加一些额外的职责。就扩展功能而言,装饰模式提供了一种比使用子类更加灵活的替代方案。2、装饰模式结构Component(抽象构建):它是具体构建和抽象装饰类的共同父类,声明了在具体构件中实现的业务方法。ConcreteComponent(具体构建):定......