前几天向几位新同事介绍项目,被问起了@login_required的实现,我说这是django框架提供的装饰器方法,验证用户是否登录,只要这样用就行了,因为自己不熟,并没有做过多解释。

今天查看django官网,忽然发现,装饰器用法并不是django框架提供的,而是python的一种语法,真心汗一个,自以为python用的很熟了,看来是井底之蛙!

恰逢周末,静下心来了解一下python的装饰器方法。

谈到代码里的装饰器,很自然的想到了设计模式中的装饰器模式,为了防止再次张冠李戴,特意翻了翻设计模式的书,确定python装饰器语法的功能就是类似于装饰器模式要实现的功能。

关于python装饰器语法,简单的说就是把要执行的方法foo用一段代码包装起来,在调用foo方法的前前后后增加一些逻辑,然后把这个新方法赋给foo。

也可以在包装的逻辑里写一个封装方法,传入参数,进行一些操作。注意一点,有多个装饰器方法包装foo时,应该是按照从下往上的顺序进行包装。

def before(pre=''):
def dec(f):
def wrapper():
print pre + " before function"
f()
return wrapper
return dec def middle(f):
def wrapper():
f()
print "middle function"
return wrapper def after(f):
def wrapper():
f()
print "after function"
return wrapper def nextbefore(f):
def wrapper():
print "nextbefore function"
f()
return wrapper @middle
@after
@nextbefore
@before("hello")
def test():
print "I'm tester" if __name__ == '__main__':
test()

打印的结果:

>>>
nextbefore function
hello before function
I'm tester
after function
middle function
>>>

如果被装饰的函数带有参数,则利用装饰器函数内部的wrap函数传参

def mydecorate(func):
def wrapper(param):
print param
func(param)
return wrapper @mydecorate
def foo1(param):
print "Hello " + param

if __name__ == "__main__":
  foo1("Andy")

返回结果:

>>>
Andy
Hello Andy

如果是带有参数装饰器,比如:

@decorate(arg)

def foo(param)

则相当于foo=decorate(arg)(foo), 即装饰器函数decorate(arg)返回结果为一个装饰器,这个装饰器再传入函数参数foo

def decorate1(para):
def real_decorate(func):
print para
def wrapper(ff):
func(ff)
return wrapper
return real_decorate @decorate1("hello")
def foo(username):
print "welcome " + username; if __name__ == "__main__":
foo("Andy")

返回结果:

>>>
hello
welcome Andy
>>>

如果带参数的装饰器还有装饰器,则等同于 foo=decorate2(decorate1(arg)(foo)) or foo=decorate2(arg1,arg2)(decorate1(arg)(foo))

python装饰器方法的更多相关文章

  1. Python 装饰器装饰类中的方法

    title: Python 装饰器装饰类中的方法 comments: true date: 2017-04-17 20:44:31 tags: ['Python', 'Decorate'] categ ...

  2. python 装饰器的缺点以及解决方法

    1.python装饰器的缺点 装饰器可以允许我们在不改变函数或犯方法的调用方式的情况下,添加额外的功能; 如下所示,我们要在中的方法之前增加装饰器check_is_admin,用来判断执行类的方法的用 ...

  3. 【python】-- 类的装饰器方法、特殊成员方法

    装饰器方法 类的另外的特性,装饰器方法:静态方法(staticmethod).类方法(classmethod).属性方法(property) 一.静态方法 在方法名前加上@staticmethod装饰 ...

  4. python装饰器通俗易懂的解释!

    1.python装饰器 刚刚接触python的装饰器,简直懵逼了,直接不懂什么意思啊有木有,自己都忘了走了多少遍Debug,查了多少遍资料,猜有点点开始明白了.总结了一下解释得比较好的,通俗易懂的来说 ...

  5. python 装饰器修改调整函数参数

    简单记录一下利用python装饰器来调整函数的方法.现在有个需求:参数line范围为1-16,要求把9-16的范围转化为1-8,即9对应1,10对应2,...,16对应8. 下面是例子: def fo ...

  6. python 装饰器学习(decorator)

    最近看到有个装饰器的例子,没看懂, #!/usr/bin/python class decorator(object): def __init__(self,f): print "initi ...

  7. Python装饰器详解

    python中的装饰器是一个用得非常多的东西,我们可以把一些特定的方法.通用的方法写成一个个装饰器,这就为调用这些方法提供一个非常大的便利,如此提高我们代码的可读性以及简洁性,以及可扩展性. 在学习p ...

  8. Python装饰器由浅入深

    装饰器的功能在很多语言中都有,名字也不尽相同,其实它体现的是一种设计模式,强调的是开放封闭原则,更多的用于后期功能升级而不是编写新的代码.装饰器不光能装饰函数,也能装饰其他的对象,比如类,但通常,我们 ...

  9. Python装饰器与面向切面编程

    今天来讨论一下装饰器.装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数 ...

随机推荐

  1. Pebbles

    Pebbles Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Sub ...

  2. BZOJ3249 : [ioi2013]game

    线段树套Treap 外层的线段树需要动态开节点 内层Treap需要注意的是,相同y坐标的点不一定是同一个点,所以需要再次离散 空间$O(n\log n)$ 时间$O(n\log^2n)$ #inclu ...

  3. 【BZOJ】3319: 黑白树

    http://www.lydsy.com/JudgeOnline/problem.php?id=3319 题意:给一棵n节点的树(n<=1e6),m个操作(m<=1e6),每次操作有两种: ...

  4. 【BZOJ】3809: Gty的二逼妹子序列

    http://www.lydsy.com/JudgeOnline/problem.php?id=3809 题意:n个元素(1<=n<=100000)每个元素有一权值<=n.q个询问, ...

  5. Contest Hunter Round #70 - 连续两大交易事件杯省选模拟赛

    orz lydrainbowcat [Problem A]「艦これ市」70万幕后交易事件 排序机器=-=.重要的是相同的处理. 我们可以从小到大添加数字,然后维护一个位置的序列.每一种相等的数字都在一 ...

  6. Genymotion填坑之路

    Genymotion是一款android的模拟器,之前用的一台电脑直接装上就可以用,后来换了一台机器,一直报获取不到IP,后来网上各种找方法,偶然发现网上说的是硬件问题: 在BIOS中将CPU的vir ...

  7. MyEclipse 10 之下Web Service 的创建和实现

    (一)Web service服务端开发 1. 新建一个Web service project, 菜单New -> Web Service Project, 2. 新建一个 Java Bean, ...

  8. Html - 仿Ios assistiveTouch 悬浮辅助球工具

    仿Ios assistiveTouch 悬浮辅助球工具 <!DOCTYPE html> <html> <head> <meta charset="u ...

  9. mysql 事务是专门用来管理insert,update,delete语句的,和select语句一点不相干

    1.mysql 事务是专门用来管理insert,update,delete语句的,和select语句一点不相干 2.一般来说,事务是必须满足4个条件(ACID): Atomicity(原子性).Con ...

  10. [SHELL实例] (转)最牛B的 Linux Shell 命令 (一)

    本文编译自commandlinefu.com ( 应该是 Catonmat ) 的系列文章 Top Ten One-Liners from CommandLineFu Explained .作为一个由 ...