函数对象可以被赋值给变量,所以,通过变量也能调用该函数。
>>> def now():
... print(‘2016‘)
...
>>> now()
2016
>>> f = now --函数对象赋值给变量
>>> f() --调用
2016
函数对象的__name__,能拿到函数的名称
>>> now.__name__
‘now‘
>>> f.__name__
‘now‘
假设我们要增强now()函数的功能,比如,在函数调用前后自动打印日志,但又不希望修改now()函数的定义,这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。
decorator就是一个返回函数的高阶函数。如下定义一个decorator
>>> def log(func):
... def wrapper(*args, **kw): --前面可变参数和关键字参数部分已讲解,=可传任何参数
... print(‘call %s():‘ % func.__name__)
... return func(*args, **kw)
... return wrapper
...
>>> @log --相当于执行now = log(now),对now函数进行重新定义。
... def now():
... print(‘2016‘)
...
>>> now()
call now():
2016
#################################################################
>>> def log2(func):
... def wrapper(*args, **kw):
... print(‘begin call‘) --调用前执行
... res = func(*args, **kw)
... print(‘end call‘) --调用后执行
... return res
... return wrapper
>>> @log2
... def pr():
... print(‘2016‘)
...
>>>
>>> pr()
begin call
2016
end call
##################################################################
>>> def log(text): --自定义text内容
... def decorator(func):
... def wrapper(*args, **kw):
... print(‘%s %s():‘ % (text,func.__name__))
... return func(*args, **kw)
... return wrapper
... return decorator
...
>>>
>>>
>>>
>>> @log(‘execute‘) --相当于执行now=log(‘execute’)(now)
... def now():
... print(‘2016‘)
...
>>> now()
execute now():
2016
>>> now.__name__
‘wrapper‘ --返回函数名,却是wrapper
##################################################################
>>> importfunctools
>>>
>>> def log(func):
... @functools.wraps(func)
... def wrapper(*args, **kw):
... print(‘call %s():‘ % func.__name__)
... return func(*args, **kw)
... return wrapper
...
>>>
>>>
>>> @log
... def now():
... print(‘2‘)
...
>>> now
<function now at 0x2ab1090d9e18>
>>> now()
call now():
2
>>> now.__name__
‘now‘
##################################################################
>>> importfunctools
>>> def log(text):
... def decorator(func):
... @functools.wraps(func)
... def wrapper(*args, **kw):
... print(‘%s %s():‘ % (text,func.__name__))
... return func(*args, **kw)
... return wrapper
... return decorator
...
>>> @log(‘Run‘)
... def now():
... print(‘2016‘)
...
>>> now()
Run now():
2016
>>> now.__name__
‘now‘
只需记住在定义wrapper()的前面加上@functools.wraps(func)即可。
本文出自 “90SirDB” 博客,请务必保留此出处http://90sirdb.blog.51cto.com/8713279/1820989
原文地址:http://90sirdb.blog.51cto.com/8713279/1820989