码迷,mamicode.com
首页 > 编程语言 > 详细

Python 装饰器

时间:2016-02-01 23:56:08      阅读:553      评论:0      收藏:0      [点我收藏+]

标签:

一、什么是装饰器

  装饰器自身就是一个函数,它是在函数上调用的装饰,也可以说用一个函数(装饰器)来”装饰”另一个函数。在代码中以@表示,很明显的是在某个函数之上出现了@,就说明装饰器装饰了其函数。重点来了,那么它为什么叫做装饰器呢?

>>> import time
>>> def extend_login(func):
>>>     def timestamp(*args,**kwargs):
>>>         print (time.ctime())    #打印当前系统时间
>>>         func(*args,**kwargs)
>>>     return timestamp    #注意这里不能加括号,因为return的是timestamp的内存地址,不可写为timestamp()
>>> 
>>> @extend_login
>>> def login(username):
>>>     print ("%s login system" % username)
>>> 
>>> login(‘Stanley‘)

  以上代码中,extend_login 就是装饰器的名称,它是一个函数,接收func作为这个函数的参数。因为在执行exntend_login函数的时候,并没有立即执行timestamp函数,而是将timestamp生成内存地址(图1),下一步直接return了timestamp的内存地址到login函数,此时的login函数已经不再是原来的它,经过了extend_login函数的装饰,已经变为了login = extend_login(login),这里的login是其内存地址;最后执行执行login函数(也就是timestamp函数。所谓装饰器是指在执行func函数之前,又执行了其他的操作(打印当前系统时间),所以说起到了装饰func函数的作用,其功能是在用户登陆之前,打印当前系统时间,这就是一个装饰器。

技术分享

图1

二、如何使用装饰器

  装饰器到底有什么使用的场景能让它物有所用呢,大多数的场景是在函数不修改原有函数的基础上,在其外部扩展一个函数的行为,修改函数或扩展原有功能;另一方如果这个功能可以被使用在很多函数上,或是函数并不是自己实现,那可以写个装饰器来实现这些功能,而不用重复编写,减少代码的冗余度。

>>> @extend_login
>>> def login():
>>>     pass

  在装饰器使用过程中,@extend_login含义是调用名为exntend_login的装饰器(其实就是个函数)来装饰login函数,那么按照如上调用等价于:

>>> login = extend_login(login)    #这里括号内的login没有(),仅仅是吧login的内存地址当做参数传递给extend_login装饰器(函数)

三、装饰器内传递参数

  在给装饰器内传递参数的时候,需要注意的是在timestamp函数内,要写多个接收参数和接收任意类型参数,也就是*args和**kwargs;如果这里没有指定接收参数,那么在login函数向装饰器内传递参数会出现报错。

>>> import time
>>> def extend_login(func):
>>>     def timestamp():    #没有参数会报错
>>>         print (time.ctime())
>>>         func()    #没有参数会报错
>>>     return timestamp
>>> 
>>> @extend_login
>>> def login(username):
>>>     print ("%s login system" % username)
>>> 
>>> login(‘Stanley‘)
TypeError: timestamp() takes no arguments (1 given)

  在装饰器调用中,会把login函数的参数传递给装饰器(图2)

技术分享

图2

四、完整示例

>>> import time
>>> def extend_login(func):
>>>     def timestamp(*args,**kwargs):
>>>         print (time.ctime())
>>>         func(*args,**kwargs)
>>>     return timestamp
>>> 
>>> @extend_login
>>> def login(username):
>>>     print ("%s login system" % username)
>>> 
>>> login(‘Stanley‘)

Mon Feb 01 11:29:40 2016
Stanley login system

基本类型装饰器的实现类似于此,一个函数被多个装饰器装饰等高级用法还会陆续更新。

Python 装饰器

标签:

原文地址:http://www.cnblogs.com/stanley-liu310/p/5176442.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!