浅析python中的装饰器decorator
最近学习python,其中decorator比较难理解,遂写一篇来总结供后续查阅。
定义一个函数,想在运行时动态的改变函数的功能,又不想改变函数本身的代码,可以使用高阶函数(可以使用函数作为参数)
装饰器函数可以简化代码,避免每个函数编写重复的代码,也可以用在python web开发中进行登录限制。
1,一般的函数调用-硬编码调用,代码中直接调用函数(直接调用原函数):
def func1():
print ("func1") def func2():
print("before")
func1()
print("after") func2()
输出为:

2,python中可将函数作为参数进行传递(高阶函数):
def func1():
print("func1") def wrapper(func): #装饰器函数
print("before")
func()
print("after")
return func #如果不写return func,函数会自动返回,默认为0 func1=wrapper(func1)
调用结果同上。
wrapper函数最后如果不返回func,再次调用func1,则会包以下错误TypeError: 'NoneType' object is not callable:

3,python中的decorator中可以简化上述调用:
def wrapper(func):
print("before")
func()
print("after")
return func @wrapper
def func1():
print("func1")
直接执行,结果同上。
4,这种装饰器执行一次调用一次,我们如果希望显示调用,则可以在函数内部封装一层:
def wrapper(func):
def inner():
print("before")
func()
print("after")
return inner @wrapper
def f():
print("call f") f()#显示调用
5,上面是无参数的装饰器,python中可以实现有参装饰器调用:
def wrapper(func):
def inner(a,b):
print("before wrapper")
func(a,b)
print("after wrapper")
return inner @wrapper
def f(a,b):
print ("call f: a+b=%d"% (a+b) ) f(2,3) # f=wrapper(f)=inner
6,有时候,不确定装饰器中参数个数的情况下,就不能使用一般参数、默认参数了,可以使用(*args, **kwargs)来自动适应变参和命名参数:
#coding:utf-8
def wrapper(func):
def inner(*args, **kwargs):
print("before %s"%func.__name__)
result=func(*args,**kwargs)
print("result of %s is %d"%(func.__name__,result))
return inner @wrapper
def f1(a,b):
print("call f1")
return a+b
@wrapper
def f2(a,b,c):
print("call f2")
return a+b+c f1(1,2)
f2(2,3,4)
7,使用functools.wraps在装饰器中包裹传进来的函数,这样就不会丢失传进来的函数的__name__等属性:
from functools import wraps def my_decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
print('wrapper')
func(*args, **kwargs) return wrapper @my_decorator
def my_fun():
print('test') #exec
my_fun()
8,装饰器在flask中的应用:
#只贴出装饰器核心代码
def login_decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
if session.get('manage_name'):
return func(*args, **kwargs)
else:
return redirect(url_for('login')) return wrapper @app.route('/post')
@login_decorator
def post():
if request.method == 'GET':
return render_template('post.html')
else:
pass
具体代码可见我的github
参考:简书
浅析python中的装饰器decorator的更多相关文章
- python中的装饰器decorator
python中的装饰器 装饰器是为了解决以下描述的问题而产生的方法 我们在已有的函数代码的基础上,想要动态的为这个函数增加功能而又不改变原函数的代码 例如有三个函数: def f1(x): retur ...
- [转] Python中的装饰器(decorator)
想理解Python的decorator首先要知道在Python中函数也是一个对象,所以你可以 将函数复制给变量 将函数当做参数 返回一个函数 函数在Python中和变量的用法一样也是一等公民,也就是高 ...
- 简单说明Python中的装饰器的用法
简单说明Python中的装饰器的用法 这篇文章主要简单说明了Python中的装饰器的用法,装饰器在Python的进阶学习中非常重要,示例代码基于Python2.x,需要的朋友可以参考下 装饰器对与 ...
- 写python中的装饰器
python中的装饰器主要用于在已有函数实现功能前附加需要输出的信息,下面将用实例展示我如何写装饰器. 首先分别尝试写装饰器装饰一个无参函数和一个有参函数(被装饰函数仅输出,无返回值情况下) def ...
- 【Python】python中的装饰器——@
对装饰器本来就一知半解的,今天终于弄清楚了,Python中的装饰器是对装饰者模式的很好运用,简化到骨子里了. python中为什么需要装饰器,看这里:http://www.cnblogs.com/hu ...
- Python 中实现装饰器时使用 @functools.wraps 的理由
Python 中使用装饰器对在运行期对函数进行一些外部功能的扩展.但是在使用过程中,由于装饰器的加入导致解释器认为函数本身发生了改变,在某些情况下——比如测试时——会导致一些问题.Python 通过 ...
- python中@property装饰器的使用
目录 python中@property装饰器的使用 1.引出问题 2.初步改善 3.使用@property 4.解析@property 5.总结 python中@property装饰器的使用 1.引出 ...
- python语法32[装饰器decorator](转)
一 装饰器decorator decorator设计模式允许动态地对现有的对象或函数包装以至于修改现有的职责和行为,简单地讲用来动态地扩展现有的功能.其实也就是其他语言中的AOP的概念,将对象或函数的 ...
- python 语法之 装饰器decorator
装饰器 decorator 或者称为包装器,是对函数的一种包装. 它能使函数的功能得到扩充,而同时不用修改函数本身的代码. 它能够增加函数执行前.执行后的行为,而不需对调用函数的代码做任何改变. 下面 ...
随机推荐
- Git Flow 分支管理简述
概述 Git 是什么 Git 是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目. Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的 ...
- 在Python中定义和使用抽象类的方法
https://www.jb51.net/article/87710.htm 像java一样python也可以定义一个抽象类. 在讲抽象类之前,先说下抽象方法的实现. 抽象方法是基类中定义的方法,但却 ...
- 在mysql命令行下执行sql文件
***********在mysql命令行下执行sql文件*********** C:\Windows\system32>cd E:\MySQL\mysql-5.7.16-winx64\bin / ...
- Atitit mysql 存储过程捕获所有异常,以及日志记录异常信息
Atitit mysql 存储过程捕获所有异常,以及日志记录异常信息 1.1. 异常的处理模式exit continue undo模式 1 1.2. 捕获所有异常使用 DECLARE ...
- numpy 随机产生数字
python数据分析的学习和应用过程中,经常需要用到numpy的随机函数,由于随机函数random的功能比较多,经常会混淆或记不住,下面我们一起来汇总学习下. 1 numpy.random.rand( ...
- 浅析LRC歌词文件
[时间:2018-12] [状态:Open] [关键词:字幕,LRC,歌词,lyric,文件格式] 0 引言 几年前(2010年左右),网络音乐流行与免费的时代,网上有大量的mp3,使用比较常见的播放 ...
- input文件上传(上传单个文件/多选文件/文件夹、拖拽上传、分片上传)
//上传单个/多个文件 <input title="点击选择文件" id="h5Input1" multiple="" accept= ...
- C#学习笔记(34)——委托传值(回忆版)
说明(2018-4-6 20:31:03): 1. 昨天晚上看三层,看完第一天的最后一节,会员的修改和增加,感觉欲仙欲死,果断关机睡觉. 2. 上午搞了半天哈利波特的原版书epub的下载,结果都没发现 ...
- 【转】Cowboy 开源 WebSocket 网络库
原文链接: http://www.cnblogs.com/gaochundong/p/cowboy_websockets.html
- Direct3D 11 Tutorial 6:Lighting_Direct3D 11 教程6:灯光
概述 在之前的教程中,世界看起来很无聊,因为所有对象都以相同的方式点亮. 本教程将介绍简单照明的概念及其应用方法. 使用的技术将是朗伯照明. 本教程的结果将修改前面的示例以包含光源. 该光源将附在轨道 ...