decorator模块是python用来专门封装装饰器的模块,使用decorator构造装饰器更加简便,同时被装饰的函数签名也保留不变
from decorator import decorator
@decorator
def check_num(func, *args, **kwargs):
if len(args) != 2:
raise Exception(‘Your args number is not two‘)
else:
return func(*args, **kwargs)
@check_num
def add(x, y):
return x + y
>>> add
>>> print add(1,2)
3
...
>>> add(1,2,3)
Traceback (most recent call last):
File "D:\PyCharm 5.0.4\helpers\pydev\pydevd_exec.py", line 3, in Exec
exec exp in global_vars, local_vars
File "", line 1, in
TypeError: add() takes exactly 2 arguments (3 given)
#可以看到这里当我们传三个参数给add()函数时,他直接从add()函数抛出类型错误异常,
#并没有进入check_num装饰器进行参数校验,可见被装饰的函数add()的签名还是他本身
#如果直接构造装饰器,那么这里将会从check_num里面抛出异常,如下:
def check_num(func):
def inner(*args,**kwargs):
if len(args) != 2:
raise Exception(‘Your args number is not two‘)
else:
return func(*args,**kwargs)
return inner
@check_num
def add(x, y):
return x + y
>>> add
>>>add(1,2,3)
Traceback (most recent call last):
File "D:\PyCharm 5.0.4\helpers\pydev\pydevd.py", line 2411, in
globals = debugger.run(setup[‘file‘], None, None, is_module)
File "D:\PyCharm 5.0.4\helpers\pydev\pydevd.py", line 1802, in run
launch(file, globals, locals) # execute the script
File "E:/code/my_project/decorator/test3.py", line 14, in
print add(1,2,3)
File "E:/code/my_project/decorator/test3.py", line 4, in inner
raise Exception(‘Your args number is not two‘)
Exception: Your args number is not two
如果想让装饰器带参数呢?
from decorator import decorator
def check(flag):
@decorator
def check_num(func, *args, **kwargs):
if flag == ‘false‘:
print ‘skip check !‘
return func(*args,**kwargs)
if len(args) != 2:
raise Exception(‘Your args number is not two‘)
else:
return func(*args, **kwargs)
return check_num
@check(‘false‘)
def add(x, y):
return x + y
>>>add
>>>add(1,2)
skip check !
3