<Del>装饰器继承</del>__call__
初衷
最近在计划着用Django写个web出来玩玩儿,在用户验证这里用装饰器简单粗暴,细分有登录验证,管理员验证。发现两个装饰器的代码仅有一丢丢的差别,第一反应是就这样吧,第二反应是如果过两天我加了验证怎么办,比如VIP,SVIP,特定渠道验证等,感觉也只有一行代码的差别,于是我想着把这抽象出来,搜了搜发现class
有一个有趣的东西__call__
.
call
class本身不具备运算能力,但加上call函数,可以让它成为一个函数那样调用,相当于c++中的bool operator()(T const&)
重载运算符;1234567891011121314#coding=utf-8class Foo: def __call__(self, *args, **kwargs): print u'Foo.__call__', args, kwargsf = Foo() # new a object Foof(1, 2, 3, four = 4) # Equal to `Foo()(1, 2, 3, four = 4)`"""result:Foo.__call__ (1, 2, 3) {'four': 4}"""
上面这样一个类,就具有了运算能力,我们可在call函数里面做相应操作
装饰器继承
知道了上面call的妙用之后,就可以来实现一个可继承的装饰器了,把各个装饰器的相同代码放在call下,重写个成员函数放不同代码,即可。
|
|
上面就是一个简单装饰器继承的例子。
更有趣的一点是,这还省去了一个小麻烦,普通装饰器需要用functools.wraps
来获取原函数的各种信息,然而上面这样写,可以直接获得原函数的所有信息如__name__
,__doc__
等