函数也是对象

要理解Python装饰器,首先要明白在Python中,函数也是一种对象,因此可以把定义函数时的函数名看作是函数对象的一个引用。既然是引用,因此可以将函数赋值给一个变量,也可以把函数作为一个参数传递或返回。同时,函数体中也可以再定义函数。
装饰器本质
可以通过编写一个纯函数的例子来还原装饰器所要做的事。
def decorator(func):
def wrap():
print("Doing someting before executing func()")
func()
print("Doing someting after executing func()")
return wrap
def fun_test():
print("func")
fun_test = decorator(fun_test)
fun_test()
# Output:
# Doing someting before executing func()
# func
# Doing someting after executing func()
fun_test所指向的函数的引用传递给decorator()函数
decorator()函数中定义了wrap()子函数,这个子函数会调用通过func引用传递进来的fun_test()函数,并在调用函数的前后做了一些其他的事情
decorator()函数返回内部定义的wrap()函数引用
fun_test接收decorator()返回的函数引用,从而指向了一个新的函数对象
通过fun_test()调用新的函数执行wrap()函数的功能,从而完成了对fun_test()函数的前后装饰
Python中使用装饰器
在Python中可以通过@符号来方便的使用装饰器功能。
def decorator(func):
def wrap():
print("Doing someting before executing func()")
func()
print("Doing someting after executing func()")
return wrap
@decorator
def fun_test():
print("func")
fun_test()
# Output:
# Doing someting before executing func()
# func
# Doing someting after executing func()
装饰的功能已经实现了,但是此时执行:
print(fun_test.__name__) # Output: # wrap
fun_test.__name__已经变成了wrap,这是应为wrap()函数已经重写了我们函数的名字和注释文档。此时可以通过functools.wraps来解决这个问题。wraps接受一个函数来进行装饰,并加入了复制函数名称、注释文档、参数列表等等功能。这可以让我们在装饰器里面访问在装饰之前的函数的属性。
更规范的写法:
from functools import wraps
def decorator(func):
@wraps(func)
def wrap():
print("Doing someting before executing func()")
func()
print("Doing someting after executing func()")
return wrap
@decorator
def fun_test():
print("func")
fun_test()
print(fun_test.__name__)
# Output:
# Doing someting before executing func()
# func
# Doing someting after executing func()
# fun_test
带参数的装饰器
通过返回一个包裹函数的函数,可以模仿wraps装饰器,构造出一个带参数的装饰器。
from functools import wraps
def loginfo(info='info1'):
def loginfo_decorator(func):
@wraps(func)
def wrap_func(*args, **kwargs):
print(func.__name__ + ' was called')
print('info: %s' % info)
return func(*args, **kwargs)
return wrap_func
return loginfo_decorator
@loginfo()
def func1():
pass
func1()
# Output:
# func1 was called
# info: info1
@loginfo(info='info2')
def func2():
pass
func2()
# Output:
# func2 was called
# info: info2
装饰器类
通过编写类的方法也可以实现装饰器,并让装饰器具备继承等面向对象中更实用的特性
首先编写一个装饰器基类:
from functools import wraps
class loginfo:
def __init__(self, info='info1'):
self.info = info
def __call__(self, func):
@wrap
def wrap_func(*args, **kwargs):
print(func.__name__ + ' was called')
print('info: %s' % self.info)
self.after() # 调用after方法,可以在子类中实现
return func(*args, **kwargs)
return wrap_func
def after(self):
pass
@loginfo(info='info2')
def func1():
pass
# Output:
# func1 was called
# info: info1
再通过继承loginfo类,扩展装饰器的功能:
class loginfo_after(loginfo):
def __init__(self, info2='info2', *args, **kwargs):
self.info2 = info2
super(loginfo_after, self).__init__(*args, **kwargs)
def after(self):
print('after: %s' % self.info2)
@loginfo_after()
def func2():
pass
func2()
# Output:
# func2 was called
# info: info1
# after: info2
以上这篇老生常谈Python进阶之装饰器就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。
# python
# 装饰器
# python装饰器使用实例详解
# python 一篇文章搞懂装饰器所有用法(建议收藏)
# python类装饰器用法实例
# Python装饰器模式定义与用法分析
# python中装饰器级连的使用方法示例
# python如何实现不用装饰器实现登陆器小程序
# python装饰器代替set get方法实例
# 可以通过
# 给大家
# 进阶
# 这是
# 文档
# 让我们
# 老生常谈
# 其他的
# 子函数
# 并在
# 希望能
# 要做
# 写了
# 作为一个
# 可以实现
# 中也
# 这篇
# 这可
# 小编
# 解决这个问题
相关文章:
宝塔新建站点为何无法访问?如何排查?
如何在Windows环境下新建FTP站点并设置权限?
深圳网站制作的公司有哪些,dido官方网站?
html制作网站的步骤有哪些,iapp如何添加网页?
如何选择香港主机高效搭建外贸独立站?
制作公司内部网站有哪些,内网如何建网站?
,柠檬视频怎样兑换vip?
胶州企业网站制作公司,青岛石头网络科技有限公司怎么样?
手机钓鱼网站怎么制作视频,怎样拦截钓鱼网站。怎么办?
如何在Golang中使用replace替换模块_指定本地或远程路径
小自动建站系统:AI智能生成+拖拽模板,多端适配一键搭建
历史网站制作软件,华为如何找回被删除的网站?
建站之星伪静态规则如何正确配置?
如何高效利用200m空间完成建站?
网页设计与网站制作内容,怎样注册网站?
电商网站制作价格怎么算,网上拍卖流程以及规则?
制作网站的基本流程,设计网站的软件是什么?
香港服务器建站指南:免备案优势与SEO优化技巧全解析
制作旅游网站html,怎样注册旅游网站?
如何零成本快速生成个人自助网站?
建站与域名管理如何高效结合?
临沂网站制作公司有哪些,临沂第四中学官网?
如何基于云服务器快速搭建网站及云盘系统?
建站主机助手选型指南:2025年热门推荐与高效部署技巧
建站之星Pro快速搭建教程:模板选择与功能配置指南
怎么将XML数据可视化 D3.js加载XML
南阳网站制作公司推荐,小学电子版试卷去哪里找资源好?
建站之星2.7模板快速切换与批量管理功能操作指南
XML的“混合内容”是什么 怎么用DTD或XSD定义
招商网站制作流程,网站招商广告语?
东莞市网站制作公司有哪些,东莞找工作用什么网站好?
制作网站哪家好,cc、.co、.cm哪个域名更适合做网站?
nginx修改上传文件大小限制的方法
寿县云建站:智能SEO优化与多行业模板快速上线指南
如何快速搭建高效WAP手机网站吸引移动用户?
制作充值网站的软件,做人力招聘为什么要自己交端口钱?
建站之星导航菜单设置与功能模块配置全攻略
制作假网页,招聘网的薪资待遇,会有靠谱的吗?一面试又各种折扣?
建站之星官网登录失败?如何快速解决?
建站主机与虚拟主机有何区别?如何选择最优方案?
如何在局域网内绑定自建网站域名?
制作门户网站的参考文献在哪,小说网站怎么建立?
网站制作免费,什么网站能看正片电影?
婚礼视频制作网站,学习*后期制作的网站有哪些?
如何通过万网虚拟主机快速搭建网站?
建站之星logo尺寸如何设置最合适?
Android滚轮选择时间控件使用详解
如何高效生成建站之星成品网站源码?
如何高效完成独享虚拟主机建站?
建站之星展会模版如何一键下载生成?
*请认真填写需求信息,我们会在24小时内与您取得联系。