11.3.6 函数(与方法)装饰器
装饰器是在函数调用之上的修饰。这些修饰仅是当声明一个函数或者方法的时候,才会应用的额外调用。
装饰器的语法以@开头,接着是装饰器函数的名字和可选的参数。紧跟着装饰器声明的是被修饰的函数和装饰函数的可选参数。
@decorator(dec_opt_args)
def func2Bdecorated(func_opt_args):
装饰器可以如函数调用一样”堆叠“起来使用多个装饰器。
@deco2
@deco1
def func(arg1, arg2, ...): pass
from time import ctime, sleep
>>> def tsfunc(func):
... def wrappedFunc():
... print '[%s] %s() called' % (ctime(), func.__name__)
... return func()
... return wrappedFunc
...
>>> @tsfunc
... def foo():
... pass
...
>>> foo()
[Thu Oct 13 15:41:26 2011] foo() called
>>>
1. 有参数和无参数的装饰器
带参数的装饰器:需要自己返回以函数作为参数的装饰器。换句话说,decomaker()用deco_args做了些事并返回函数对象,而该函数对象正是以foo作为其参数的装饰器。
2. 什么是装饰器
可以用装饰器来:引用日志;增加计时逻辑来检测性能;给函数加入事务的能力
11.4 传递函数
函数是可以被引用的,也作为参数传入函数,以及作为列表和字典等容器对象的元素函数有一个独一无二的特征使它同其他对象区分开来,那就是函数是可以调用的。
>>> def convert(func, seq):
... return [func(item) for item in seq]
...
>>> convert(float, (1,2,3,4,5,'4'))
[1.0, 2.0, 3.0, 4.0, 5.0, 4.0]
>>>
11.5 Formal Arguments
11.5.1 位置参数
位置参数必须以在被调用函数中定义的准确顺序来传递。另外,没有任何默认参数的话,传入函数(调用)的参数的精确的数目必须和声明的数字一致。
可以不按位置地将关键字参数传入函数,给出关键字来匹配其在参数列表中的合适的位置是被允许的。
11.5.2 默认参数
对于默认参数如果在函数调用时没有为参数提供值则使用预先定义的默认值。C++也支持默认参数。
Python中默认值声明变量的语法是所有的位置参数必须出现在任何一个默认参数之前。
>>> from urllib import urlretrieve
>>> def firstNonBlank(lines):
... for eachline in lines:
... if not eachline.strip():
... continue
... else:
... return eachline
...
>>> def firstLast(webpage):
... f = open(webpage)
... lines = f.readlines()
... f.close()
... print firstNonBlank(lines), lines.reverse()
... print firstNonBlank(lines),
...
>>> def download(url = "http://www", process = firstLast):
... try:
... retval = urlretrieve(url)[0]
... except IOError:
... retval = None
... if retval:
... process(retval)
...
>>> download()
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
None
</html>