社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

Python装饰器

小白学视觉 • 3 年前 • 258 次点击  

点击上方小白学视觉”,选择加"星标"或“置顶

重磅干货,第一时间送达

所谓装饰器(decorator)指的是在Python代码运行期间动态的增加函数功能的一种方式。在上一节我们知道Python函数在运行时允许返回函数,而函数作为对象也可以被赋值给其他变量来调用,比如:

>>> def LAL():
...    print('kobe')
...
>>> f = LAL
>>> f()
kobe

每个函数对象都有一个_ _name_ _属性,调用该属性我们可以取得该函数的名称:

>>> LAL.__name__
'LAL'
>>> f.__name__
'LAL'

而装饰器(decorator)的作用即在于可以使得我们在调用 LAL 函数的时候,使得该函数功能增强,比如说在调用该函数前后自动打印日志,但又不能改变 LAL函数的定义。所以,Python装饰器的本质在于它是一个可以返回函数的高阶函数。我们来定义一个decorator,使得函数在调用前后能打印日志。

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

仔细观察上述代码,我们定义的log函数作为一个decorator可以接受像func这样的函数作为参数,作为高阶函数它也可以返回一个函数。下面再利用Python的@语法,在重新定义 LAL函数时调用装饰器:

@log
def LAL():
print('kobe')

之后再调用 LAL 函数时,不仅会运行 LAL 函数本身也会打印装饰器所设置的一串日志。

>>> LAL()
call LAL():
kobe

@语法的作用相当于执行了如下语句:

LAL = log(LAL)

如果decorator本身也需要传入参数,那装饰器的定义则需要更加复杂一点。我们可以自定义log的文本:

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

可以看见的是,我们经过三层嵌套后使得装饰器本身可以传入文本参数,其用法如下:

@log('execute')
def LAL():
print('kobe')

函数执行结果如下:

>>> LAL()
execute LAL():
kobe

相较于两层嵌套,三层嵌套的decorator相当于执行了如下语句:

>>> LAL = log('execute')(LAL)

可以简单分析一下这个语句。先执行log('execute'),返回的是装饰器函数,调用该返回函数,其参数是LAL函数,最后的返回值则是folder函数。不管两层还是三层嵌套,decorator的定义都是这种套路,我们开头时提到了函数作为对象是有__name__属性的,但经过装饰器装饰后的函数,其__name__属性由原先的'LAL'变成了'folder':

>>> LAL.__name__
'folder'

所以这里我们还需要导入functools模块,使用functools.wraps使得经装饰器装饰前后的函数对象名保持不变,完整的decorator定义方法如下:

import functools

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

decorator可以增强函数的功能,虽然不容易定义清楚,但使用起来非常便利。

好消息!

小白学视觉知识星球

开始面向外开放啦👇👇👇




下载1:OpenCV-Contrib扩展模块中文版教程
在「小白学视觉」公众号后台回复:扩展模块中文教程即可下载全网第一份OpenCV扩展模块教程中文版,涵盖扩展模块安装、SFM算法、立体视觉、目标跟踪、生物视觉、超分辨率处理等二十多章内容。

下载2:Python视觉实战项目52讲
小白学视觉公众号后台回复:Python视觉实战项目即可下载包括图像分割、口罩检测、车道线检测、车辆计数、添加眼线、车牌识别、字符识别、情绪检测、文本内容提取、面部识别等31个视觉实战项目,助力快速学校计算机视觉。

下载3:OpenCV实战项目20讲
小白学视觉公众号后台回复:OpenCV实战项目20讲 即可下载含有20个基于OpenCV实现20个实战项目,实现OpenCV学习进阶。

交流群


欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~



Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/138278