博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
浅析python中的装饰器decorator
阅读量:6812 次
发布时间:2019-06-26

本文共 2333 字,大约阅读时间需要 7 分钟。

最近学习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,函数会自动返回,默认为0func1=wrapper(func1)

 调用结果同上。

wrapper函数最后如果不返回func,再次调用func1,则会包以下错误TypeError: 'NoneType' object is not callable:

 3,python中的decorator中可以简化上述调用:

def wrapper(func):    print("before")    func()    print("after")    return func@wrapperdef func1():    print("func1")

直接执行,结果同上。

4,这种装饰器执行一次调用一次,我们如果希望显示调用,则可以在函数内部封装一层:

def wrapper(func):    def inner():        print("before")        func()        print("after")    return inner@wrapperdef 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@wrapperdef f(a,b):    print ("call f: a+b=%d"% (a+b) )f(2,3) # f=wrapper(f)=inner

6,有时候,不确定装饰器中参数个数的情况下,就不能使用一般参数、默认参数了,可以使用来自动适应变参和命名参数:

#coding:utf-8def 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@wrapperdef f1(a,b):    print("call f1")    return a+b@wrapperdef f2(a,b,c):    print("call f2")    return a+b+cf1(1,2)f2(2,3,4)

7,使用functools.wraps在装饰器中包裹传进来的函数,这样就不会丢失传进来的函数的__name__等属性:

from functools import wrapsdef my_decorator(func):    @wraps(func)    def wrapper(*args, **kwargs):        print('wrapper')        func(*args, **kwargs)    return wrapper@my_decoratordef my_fun():    print('test')#execmy_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_decoratordef post():    if request.method == 'GET':        return render_template('post.html')    else:        pass

具体代码可见我的

 

参考:

转载于:https://www.cnblogs.com/hoaprox/p/9481884.html

你可能感兴趣的文章
BZOJ2653middle——二分答案+可持久化线段树
查看>>
BZOJ4543[POI2014]Hotel加强版——长链剖分+树形DP
查看>>
x=n; y=1; while(x>=(y−1)∗(y−1)) y++; 以上程序的时间复杂度为 ?
查看>>
A joke about regular expression
查看>>
【UIKit】UITableView 5
查看>>
常用颜色代码
查看>>
python学习笔记
查看>>
布局修改就保存
查看>>
Android 虚拟机快捷键
查看>>
前端性能优化--图片懒加载(lazyload image)
查看>>
ubuntu下IP、DNS配置
查看>>
linux下order by 报出ORDER BY clause is not in SELECT list
查看>>
CentOS 7设置开机启动服务,添加自定义系统服务
查看>>
《让人无法说 NO的攻心说话术》摘要
查看>>
db2 reorg(转)
查看>>
1032 Sharing
查看>>
symbolicatecrash App Bug 分析工具
查看>>
深入浅出Hadoop: 高效处理大数据
查看>>
云南满泽生物科技有限公司 满泽玛卡玛咖精片 东革阿里 奶昔
查看>>
转载——yum源的超级简单配置
查看>>