函数定义的decorator |
(参看语言手册8.6节)
decorator(修饰符)在函数或者类的定义的前面可以加上一个或几个以 @ 符号开头的名字,这种描述称为紧随其后的函数或类的 decorator(修饰符)。实际上,能作为修饰符的名字必须是一个有定义的函数的名字,而这个函数应该是一个 "高阶函数"。具体说:写在函数定义前面的修饰符的名字应该约束到一个函数对象,相应的函数应该以函数对象为参数,其返回值也是一个函数对象;写在类定义前面的名字应表示一个函数对象,它以类对象为参数,其返回值也应该是一个类对象。 例如有函数定义 @decor def func (...) : ... ...就相当于写 def func (...) : ... ... func = decor(func)也就是说,先定义函数 func,然后在给 func 赋以其原来的定义经过 decor 加工之后得到的那个函数对象。至于怎么加工,完全是 decor 函数的事情,可以根据需要定义。 我们把这种加工函数的函数称为 "修饰函数",这种函数通常是在原函数的基础上增加一些通用的功能。当然,Python 提供了这种机制,怎么使用完全是程序员自己的事情。 Python 里的函数也是对象,定义函数就是构造出所需的函数对象并将其是作为相应函数名的值。这种对象完全可以作为参数送给函数使用,函数也完全可以返回另一个函数作为它的执行结果。 与此类似,类也是对象。定义类就是构造一个类对象,并将其作为相应类名的值。给类定义加修饰符,就是允许定义用函数去加工程序里定义的类。 当然,这种加工的意义是程序员自己的事情。例如可以定义下面的无用加工函数 def void (obj) : def void0 (*args) : pass return void0 @void def func (x) : return x+1void 把任何函数都加工成什么也不做,也不返回值的函数。 文档 PIP 318 包含有关 decorator 的详细说明和一些实例,见 Python 文档里 What is new 部分中的 What is new in Python2.3。
自定义 decorator下面是一个自己定义的 decorator 函数,用它装饰的函数将输出运行时间。后面是个例子:def timefunc (func) : def __decorator(*args) : begin = time() x = func(*args) print(time() - begin) return x return __decorator @timefunc def testfunc () : print('test begin') for i in range(10000000) : pass print('test end')执行 testfunc(),就会看到它在正常完成其工作外,还输出自己的执行时间。 这个 decorator 可以用于装饰具有任意的参数和返回值的函数。 几个有定义的 decorator@classmethod:这个标注只用在类定义里,用于说明被标注和函数是一个类方法。classmethod(function) 是一个内置函数。类方法以其定义所在的类对象作为隐含的第一个实参(就像实例方法以实例对象作为隐含的第一个实参)。类方法定义里的第一个形参在调用时将引用这个类的类对象本身,也可以有更多的形参。类方法可以从其定义所在的类出发去调用,也可以从该类的实例对象出发其调用。假设在 C 类里定义类类方法 fun,c 的值是 C 类的实例对象,可以写 C.fun(...) 或者 c.f(...)。 @staticmethod:这个标注只用在类定义里,用于说明被标注和函数是一个静态方法。staticmethod(function) 是一个内置函数。与类方法不同的是静态方法没有隐含的第一个参数。同样可以通过类名或类实例调用它。 |
本页及相关页面(除另声明者外)由裘宗燕创建维护,可自由用于各种学习活动。其他使用需得到作者许可。 |