比如有下面如下的代码,每个函数都需要判断debug的是否为True,而默认的debug为False
def a(x,debug=False):
if debug:
print('calling a')
def b(x,y,z,debug=False):
if debug:
print('calling b')
def c(x,y,debug=False):
if debug:
print('calling c')
上面的代码可以编写一个装饰器为被包装的函数添加额外的参数来简化,但是添加的参数不能影响到该函数已有的调用约定。定义如下的一个装饰器
def optional_debug(func):
@wraps(func)
def wrapper(*args,debug=False,**kwargs):
if debug:
print('Calling',func.__name__)
return func(*args,**kwargs)
return wrapper
@optional_debug
def spam(a,b):
print(a,b)
spam(1,2)
>>>1,2
spam(1,2,debug=True)
>>>Calling spam
1,2
利用装饰器给类定义打补丁
我们想检查一部分类的定义,以此来修改类的行为,但是不想通过继承或者元类的方式来做
我们可以用一个类装饰器重写__getattribute__
def log_getattribute(cls):
print(cls)
orig_getattribute=cls.__getattribute__
def new_getattribute(self,name):
print('geting:',name)
return orig_getattribute(self,name)
cls.__getattribute__=new_getattribute
return cls
@log_getattribute
class A:
def __init__(self,x):
self.x=x
def spam(self):
pass
(1) 首先通过orig_getattribute=cls.__getattribute__将初始的__getattribute__方法赋值给orig_getattribute,便于在new_getattribute调用
(2) 然后通过cls.__getattribute__=new_getattribute将类的__getattribute__赋值为new_getattribute,这样在类中调用__getattribute__的时候,其实是调用的new_getattribute
(3) 最后return cls
a=A(42)
print(a.x)
运行结果:
geting: x
42
@font-face { font-family: "Times New Roman"; }@font-face { font-family: "宋体"; }p.MsoNormal { margin: 0pt 0pt 0.0001pt; text-align: justify; font-family: "Times New Roman"; font-size: 10.5pt; }span.msoIns { text-decoration: underline; color: blue; }span.msoDel { text-decoration: line-through; color: red; }div.Section0 { }