python-装饰器简述
装饰器是什么
用来修饰别的函数的函数就可以称之为装饰器
这种函数的参数一般就是另外一个函数
也就是说,调用这种函数,需要给这种函数传参,且参数是函数
@语法糖
@语法糖一般用来表示装饰器函数
不用@也可以达到装饰函数的目的,下面会有演示
函数嵌套
在一个函数中定义另外一个函数
def f1(arg="aaa"):
def f2():
return "hello"
def f3():
return "hi"
def f4():
return "haha"
print f2()
print f3()
print f4()
这个f1函数有默认参数,所以可以不传参执行
执行f1()调用之后
执行结果如下:
hello
hi
haha
在函数里返回函数
def hi(arg="aaa"):
def greet():
return "bbb"
def welcome():
return "ccc"
if arg == "aaa":
return greet
else:
return welcome
a = hi()
print(a)
print (a())
这里同样使用了默认参数,则a = hi() 会命中 if arg == "aaa"这个逻辑
返回greet,注意在这里,greet是函数,不是字符串,如果是返回字符串,则要返回的是 return "greet"这种
上面这段代码执行的结果是
<function greet at 0x7f75f7a0e1b8>
bbb
为什么是这样的执行结果呢?第一个地方 print(a),打印的是a = hi()的结果
我们可以看到,hi()的返回结果都是在return一个函数,要么是greet函数,要么是welcome函数
函数就是对应一个地址,所以第一处打印的是这个函数的地址
第二处做了a的调用,即a(),则打印返回的函数即greet函数执行的结果,即bbb
将函数作为参数传给另外一个函数
def hi():
return "hi"
def hello(func):
print("before func()")
print(func())
hello(hi)
执行结果是
before func()
hi
这里把hi这个函数作为参数传给hello函数
hello函数先打印一句自身的输出before func()
再执行这个被传入的函数
我们可以看到,通过装饰器,我们可以在一个函数被调用前干一些需要的事情
不用@实现装饰器
def hi(a_func):
def hello():
print("I am doing some boring work before executing a_func()")
a_func()
print("I am doing some boring work after executing a_func()")
return hello
def haha():
print("I am the function which needs some decoration ")
haha = hi(haha)
print haha()
运行结果:
I am doing some boring work before executing a_func()
I am the function which needs some decoration
I am doing some boring work after executing a_func()
None
这个就是装饰器,起到了用hi函数装饰了haha函数的功能
那么怎么用@语法糖实现呢
def hi(a_func):
def hello():
print("I am doing some boring work before executing a_func()")
a_func()
print("I am doing some boring work after executing a_func()")
return hello
@hi
def haha():
print("I am the function which needs some decoration ")
haha()
可以看到,装饰器就是用希望装饰别的函数的函数,比如 ,希望用A装饰B
就在定义B函数的上一行,写上 @A
def A():
pass
@A
def B():
pass
总结:理解就是装饰器其实就是这样一种函数:带参数的,且参数是另外一个函数的函数
使用装饰器的目的一般是为了在运行时改变函数的一些属性/行为,就可以给这个函数加上装饰器,让装饰器去在这个函数被调用前后,干一些你想做的事情
wraps干什么的?
我们修改下上面的代码,多记录一点东西
def hi(a_func):
def hello():
print("I am doing some boring work before executing a_func()")
a_func()
print("I am doing some boring work after executing a_func()")
return hello
@hi
def haha():
print("I am the function which needs some decoration ")
haha()
print(haha.__name__)
我们的意图是打印haha这个函数的函数名,但实际上打印的是hello
为什么?
因为haha这个函数使用装饰器之后,haha的行为部分被装饰器函数改变了
可以看到,用hi函数装饰了haha之后,返回的是hello函数,那么当我们需要拿到被装饰函数的函数名,还有其他属性的时候怎么做呢?
使用functools.wraps方法
from functools import wraps
def hi(a_func):
@wraps(a_func)
def hello():
print("I am doing some boring work before executing a_func()")
a_func()
print("I am doing some boring work after executing a_func()")
return hello
@hi
def haha():
print("I am the function which needs some decoration ")
haha()
print(haha.__name__)
执行结果如下:
I am doing some boring work before executing a_func()
I am the function which needs some decoration
I am doing some boring work after executing a_func()
haha
正是我们想要的结果
@wraps接受一个函数来进行装饰,并加入了复制函数名称、注释文档、参数列表等等的功能。这可以让我们在装饰器里面访问在装饰之前的函数的属性。
举一个记录日志的例子
from functools import wraps
def logit(func):
@wraps(func)
def with_logging(*args, **kwargs):
print(func.__name__ + " was called")
return func(*args, **kwargs)
return with_logging
@logit
def addition_func(x):
"""Do some math."""
return x + x
result = addition_func(4)
# Output: addition_func was called
python-装饰器简述的更多相关文章
- 关于python装饰器
关于python装饰器,不是系统的介绍,只是说一下某些问题 1 首先了解变量作用于非常重要 2 其次要了解闭包 def logger(func): def inner(*args, **kwargs) ...
- python装饰器通俗易懂的解释!
1.python装饰器 刚刚接触python的装饰器,简直懵逼了,直接不懂什么意思啊有木有,自己都忘了走了多少遍Debug,查了多少遍资料,猜有点点开始明白了.总结了一下解释得比较好的,通俗易懂的来说 ...
- Python 装饰器学习
Python装饰器学习(九步入门) 这是在Python学习小组上介绍的内容,现学现卖.多练习是好的学习方式. 第一步:最简单的函数,准备附加额外功能 1 2 3 4 5 6 7 8 # -*- c ...
- python 装饰器修改调整函数参数
简单记录一下利用python装饰器来调整函数的方法.现在有个需求:参数line范围为1-16,要求把9-16的范围转化为1-8,即9对应1,10对应2,...,16对应8. 下面是例子: def fo ...
- python 装饰器学习(decorator)
最近看到有个装饰器的例子,没看懂, #!/usr/bin/python class decorator(object): def __init__(self,f): print "initi ...
- Python装饰器详解
python中的装饰器是一个用得非常多的东西,我们可以把一些特定的方法.通用的方法写成一个个装饰器,这就为调用这些方法提供一个非常大的便利,如此提高我们代码的可读性以及简洁性,以及可扩展性. 在学习p ...
- 关于python装饰器(Decorators)最底层理解的一句话
一个decorator只是一个带有一个函数作为参数并返回一个替换函数的闭包. http://www.xxx.com/html/2016/pythonhexinbiancheng_0718/1044.h ...
- Python装饰器由浅入深
装饰器的功能在很多语言中都有,名字也不尽相同,其实它体现的是一种设计模式,强调的是开放封闭原则,更多的用于后期功能升级而不是编写新的代码.装饰器不光能装饰函数,也能装饰其他的对象,比如类,但通常,我们 ...
- Python装饰器与面向切面编程
今天来讨论一下装饰器.装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数 ...
- python装饰器方法
前几天向几位新同事介绍项目,被问起了@login_required的实现,我说这是django框架提供的装饰器方法,验证用户是否登录,只要这样用就行了,因为自己不熟,并没有做过多解释. 今天查看dja ...
随机推荐
- java 压缩文件
package folder; import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundExcept ...
- asp.net mvc 5 关闭xss过滤
在控制器方法的头部添加 [ValidateInput(false)] 如果向mvc服务端提交带html标签的内容就会导致校验失败异常,从而得不到想要的结果,关闭的方法是在相应方法头部添加 ...
- html学习第一弹の常用标签的归类
HTML初步学习: 行内元素:只占据他对应标签的边框所包含的空间,默认横向排布. 块级元素:块级元素占据其父元素(容器)的整个空间,因此创建了一个块,通常浏览器会在块级元素前后另起一行,默认竖向排布. ...
- Java最大公约数和最小公倍数的求法(辗转相除法)
这道题计算了三个数的最小公倍数 import java.util.Scanner; public class D { public static int gcd(int a,int b) { int ...
- 原生js获取left值和top值
在用js做动态效果时,通常需要获取元素绝对定位中的left和top属性值.比如做一个碰撞广告,就要不停的获取元素的top和left属性值. 需要注意的事:取值的元素必须要设置position:abso ...
- python函数学习(一)
1.parse_known_args()和parse_args()函数 该函数为命令行解析函数,调用时需要import argparse(命令行选项.参数和子命令的解析器). 以下内容摘自python ...
- Cesium 获取鼠标当前位置的模型高度,地形高度,OSGB高度,及其经纬度。
var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene._imageryLayerCollection);var ray,posit ...
- css3新单位vw、vh的使用详解
响应式布局的单位我们第一时间会想到通过rem单位来实现适配,但是它还需要内嵌一段脚本去动态计算跟元素大小. 比如: (function (doc, win) { let docEl = doc.doc ...
- MySQL数据库学习二 MSQL安装和配置
2.1 下载和安装MySQL软件 2.1.1 基于客户端/服务器(C/S)的数据库管理系统 服务器:MySQL数据库管理系统 客户端:操作MySQL服务器 2.1.2 MySQL的各种版本 社区版(C ...
- 【Python】 http客户端库requests & urllib2 以及ip地址处理IPy
requests requests是个HTTPClient库,相比于urllib,urllib2等模块比更加简洁易用 ■ get请求 作为示例,讲一下关于requests如何发起并处理一个get请求 ...