Python
342 浏览 5 years, 11 months
10.3 实现装饰器
版权声明: 转载请注明出处 http://www.codingsoho.com/实现装饰器
使用函数作为装饰器
- 简单容易实现
- 支持不同种类的被装饰对象
def wrapper_decor(f):
def wrapper(*args):
print("Change behavior of original function")
print("Call original function")
f(*args)
print("Call originnal function done")
return wrapper
@wrapper_decor
def hello(name):
print("How are you? {}".format(name))
参数的传递
- 装饰器如何处理拥有不同参数被装饰函数
*args
- 变长位置参数**kwargs
- 变长关键字参数- ,* 在定义的时候收集变长参数,在调用函数时候扩展变长参数
print(*[1,2,3]) -> print(1,2,3)
Functions With Arbitrary Positional Arguments
- Functions that contains variable number of arguments
print(1)
print(1,2,3,4)
print(1,2,3,4,5,6,7)
How to collect these arguments?
Definition
def func(arg1, *args)
举例:
def foo(name, age, *attrs):
print(name, age, attrs)
foo(Zhang San, 18, male, China)
# Zhang San 18 (male, China)
- Functions that contains variable number of keyword arguments
datetime.datetime(2014,3,20, hour=12, minute=20, second=55)
datetime.datetime(2014,3,20, hour=12, minute=20)
datetime.datetime(2014,3,20)
How to collect these arguments?
Definition
def func(arg1, **kws)
举例:
def foo(name, age, **attrs):
print(name, age, attrs)
foo(Zhang San, 18, male, China)
# TypeError Traceback (most recent call last) <ipython-input-223-660e7e4e6b91> in <module>() ----> 1 foo(Zhang San, 18, male, China)
# TypeError: foo() takes 2 positional arguments but 4 were given
foo(Zhang San, 18, sex=male, nationality=China)
# Zhang San 18 {nationality: China, sex: male}
使用类作为装饰器
- 类可以作为一个很好的容器来存放要被装饰函数的一些信息
- 类的实例必须可以像函数一样使用
__call__()
方法
class decor():
def __init__(self, number):
print("Decorate funtion")
self.number = number
def __call__(self, f):
print("Second decorating")
def wrapper(*args, **kws):
print("Before running original function")
for x in range(self.number):
f(*args, **kws)
print("Aftere running original function")
return wrapper
@decor(3)
def hello(name):
print(name)
练习
用类来实现一个装饰器,其对被装饰函数的执行时间进行统计,统计其执行了多少秒。要求: – 用类来实现这个装饰器 – 可以通过参数来控制执行的次数 – 被装饰函数的参数类型,个数任意
装饰过程中的类型转换
- 将函数装饰成类的实例
- 将类装饰成函数
将函数装饰成类的实例
def decor_to_class(func):
class Wrapper():
def __call__(self, *args, **kws):
print("Inside a callable")
func(*args, **kws)
return Wrapper() # 返回一个callable对象
@decor_to_class
def hello(name):
print("Hello", name)
将类装饰成函数
def decor_to_func(cls):
def wrapper(*args, **argv):
print("Add some behavior here")
ins = cls(*args, **argv)
return ins
return wrapper #返回一个函数对象
@decor_to_func
class Foo():
def hello(self, name):
print("Hello", name)