简单理解Python中的装饰器
作者:Yi_Zhi_Yu 发布时间:2021-06-18 01:44:21
Python的装饰器可以实现在代码运行期间修改函数的上下文, 即可以定义函数在执行之前进行何种操作和函数执行后进行何种操作, 而函数本身并没有任何的改变。
首先, 我们先定义一个函数, 这个函数可以输出我的个人昵称:
def my_name():
print "Yi_Zhi_Yu"
my_name() # Yi_Zhi_Yu
那假如我需要在个人昵称输出前, 在输出我的个人uid呢, 当然, 要求是不改动现有的my_name函数, 这个时候就可以使用装饰器了
首先, 装饰器也是个函数, 其次, 他需要接受一个参数,该参数表示了要被装饰的函数(即my_name):
def my_info(func):
def wrapper(*args, **params):
print 218
return func(*args, **params)
return wrapper
然后与相应的被装饰函数关联起来的方法就是使用@my_info写在被装饰函数的前面
@my_info
def my_name():
print "Yi_Zhi_Yu"
最后, 在执行my_name的时候, 就能既输出我的uid, 又能输出我的昵称了
my_name()
#218
#Yi_Zhi_Yu
在上面, 最让我们疑惑的是装饰器函数定义里面的wrapper函数, 装饰器本身返回的是wrapper函数的定义, 而wrapper中则定义了对被装饰函数(my_name)的调用, func表示的就是被装饰函数, 说白了, 装饰器只是把某个不得改动的函数(a)放到另一个函数(b)中, 在b里面调用a, 在调用前后就可以做所谓的看起来像装饰的工作了。
my_info的最终返回的wrapper函数的定义, 并不是执行结果,只有当wrapper真正执行的时候, 才会真正的执行my_name方法, 这就是闭包时所说的内容。
wrapper中的参数, 实际上则是传递给func(实际上是my_name)的参数
因为装饰器也是个函数, 那么装饰器自己的能不能有参数传递呢。可以, 不过需要定义一个更高阶的函数, 也就是外面还要套一层函数, 比如, 我还要输出我的自定义的一个信息,需要传递参数
def c_info(text):
def my_info(func):
def wrapper(*args, **params):
print text
print 218
return func(*args, **params)
return wrapper
return my_info
#使用装饰器
@c_info("Tony")
def my_name():
print "Yi_Zhi_Yu"
my_name()
#Tony
#218
#Yi_Zhi_Yu
与前面的那个装饰器相比, 仅仅是多了个外层, 内层也仅仅是增加了对外层传入参数(text)的调用
总而言之, Python在函数定义中支持了对oop思想中的装饰器的实现, 其本质也只是使用了闭包的思路, 延迟调用, 并在调用前后增加自己的其他实现内容
Ps: 以上皆为学习笔记, 附带自己的理解, 难免有偏差, 如有发现纰漏, 还望指正


猜你喜欢
- 我用asp+access写程序, sql="select *&
- 当今,有一点可以肯定的是,设计的领域在扩大,这是一个需要设计的世界。拒最新的统计资料显示,中国目前已有正规的设计学院教学机构700多所,并且
- <!doctype html> <html> <head> <meta charset="
- 在cmd下运行go程序或者是GOLAND的Terminal下运行go程序会出现中文乱码的情况。go run ttypemain.go����
- 【前言】一般我们在使用ElementUI组件库的时候,在使用el-table时,背景通常是白色的,但有时候不能满足我们的实际需求,我想让el
- 代码如下:<% '功能:取得文件扩展名 Function getFileExt(sFileNam
- 这两天一直在看tensorflow中的读取数据的队列,说实话,真的是很难懂。也可能我之前没这方面的经验吧,最早我都使用的theano,什么都
- 我和朋友对此的看法有分歧,我明明记得有不需要返回的时候的?你的看法是对的,例如在表中删除记录。我们来看看下面的例子——在Employee表中
- 取余函数 PHP取余函数 PHP两个取余 MOD(x,y) x%yMOD例如:9/3,9是被除数,3为除数.mod函数是一个求余函数,其格式
- 我们可以利用Session对象来进行注册验证。Session对象会帮我们把某一用户的信息保留下来,让后续的网页读取。我们就可以在用户注册成功
- 在Transact-SQL语句中,我们主要使用OpenDataSource函数、OPENROWSET 函数,关于函数的详细说明,请参考SQL
- 本文实例讲述了php多进程中的阻塞与非阻塞操作。分享给大家供大家参考,具体如下:我们通过pcntl_fork来创建子进程,使用pcntl_w
- 下面是具体的步骤,试用于pycharm2016(亲测)1. File-->settings-->editor--&g
- 一年一度的双十一就快到了,各种砍价、盖楼、挖现金的口令将在未来一个月内充斥朋友圈、微信群中。玩过多次双十一活动的小编表示一顿操作猛如虎,一看
- 下面先来看一个例子:import requestsresult=requests.get("http://data.1
- vim有各种强大的插件,这不仅归功于其提供的用来编写插件的脚本语言vimL,还得益于它良好的接口实现,从而支持python等语言编写插件。当
- 让你成功安装vscode中go的相关插件注意:该演示环境是windows环境,linux和mac环境操作思路一样vscode中有很多go的相
- 下面把角色分为两种,普通用户和管理员用户,至少对于普通用户来说,直接修改DB是不可取的,要有用户注册的功能,下面就开始进行用户注册的开发。用
- 这段代码用到vuejs和vue-resouece。实现对接智能提示接口,并通过上下键选择提示项,按enter进行搜索<!DOCTYPE
- Embedding的近邻搜索是当前图推荐系统非常重要的一种召回方式,通过item2vec、矩阵分解、双塔DNN等方式都能够产出训练好的use