新闻动态

聊聊Python中的@符号是什么意思

发布日期:2022-01-03 01:29 | 文章来源:源码中国

Python中的@符号是装饰器的意思。Python中装饰器本质上就是一个函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外的功能,装饰器的返回值也是一个函数对象(函数的指针)。

  • 实质:是一个函数
  • 参数:是你要装饰的函数名(并非函数调用)
  • 返回:是装饰完的函数名(也不是函数调用)
  • 作用:为已经存在的对象添加额外的功能。
  • 特点:不需要对对象做任何的代码上的变动。

Python装饰器有很多经典的应用场景,比如:插入日志,性能测试,事务处理,权限校验等。装饰器是解决这类问题的绝佳设计。

装饰器最大的作用就是对于我们已经写好的程序,我们可以抽离出一些雷同的代码组件多个特定的装饰器,这样我们就可以针对不同的需求去使用特定的装饰器,这时,因为源码去除了大量泛化的内容而使得源码具有更加清晰的逻辑。

定义一个能打印日志的doctorator:

def log(func):
 def wrapper(*args, **kw):
  print('call %s():' % func.__name__)
  return func(*args, **kw)
 return wrapper

@log
def now():
 print('2021-3-25')

if __name__ == '__main__':
 now()

执行结果:

函数对象有一个__name__属性,可以拿到函数的名字。

调用now()函数,不仅会运行now()函数本身,还会在运行now()函数前打印一行日志。

把@log放到now()函数的定义处,相当于执行了语句:

now = log(now)

wrapper()函数的参数定义是(*args,**kw),因此,wrapper()函数可以接收任意参数的调用。在wrapper()函数内,首先打印日志,再紧接着调用原始函数。

如果decorator本身需要传入参数,那就需要编写一个返回decorator的高阶函数:

def log(text):
 def decorator(func):
  def wrapper(*args, **kw):
print('%s %s():' % (text, func.__name__))
return func(*args, **kw)
  return wrapper
 return decorator

@log('execute')
def now():
 print('2015-3-25')

if __name__ == '__main__':
 now()

执行结果:

和两层嵌套的decorator相比,3层嵌套的效果是这样的:

now = log('execute')(now)

首先执行log(‘execute'),返回的是decorator函数,再调用返回的函数,参数就是now函数,返回值最终是wrapper函数。

函数也是对象,它有__name_等属性,但你去看经过decorator装饰之后的函数,他们的__name__已经从原来的'now'变成了'wrapper':

print(now.__name__) #输出:wrapper

因为返回的那个wrapper()函数名字就是'wrapper',所以,需要把原始函数的__name__等属性赋值到wrapper()函数中,否则,有些依赖函数签名的代码执行就会出错。

Python内置的functiontools.wraps就是干这个事的,所以,一个完整的decorator的写法如下:

import functools
def log(func):
 @functools.wraps(func)
 def wrapper(*args, **kw):
  print('call %s():' % func.__name__)
  return func(*args, **kw)
 return wrapper

或者

import functools
def log(text):
 def decorator(func):
  @functools.wraps(func)
  def wrapper(*args, **kw):
print('%s %s():' % (text, func.__name__))
return func(*args, **kw)
  return wrapper
 return decorator

总结

到此这篇关于Python中@符号是什么意思的文章就介绍到这了,更多相关Python中@符号内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!

版权声明:本站文章来源标注为YINGSOO的内容版权均为本站所有,欢迎引用、转载,请保持原文完整并注明来源及原文链接。禁止复制或仿造本网站,禁止在非www.yingsoo.com所属的服务器上建立镜像,否则将依法追究法律责任。本站部分内容来源于网友推荐、互联网收集整理而来,仅供学习参考,不代表本站立场,如有内容涉嫌侵权,请联系alex-e#qq.com处理。

相关文章

实时开通

自选配置、实时开通

免备案

全球线路精选!

全天候客户服务

7x24全年不间断在线

专属顾问服务

1对1客户咨询顾问

在线
客服

在线客服:7*24小时在线

客服
热线

400-630-3752
7*24小时客服服务热线

关注
微信

关注官方微信
顶部