该文章持续跟新,看见好的写法就往上放
灵感来自bottle源码中描述符的适用
下面是模拟bottle描述符大致的写法
class Describer(object): def __init__(self): self._func = None # 用__call__实现类的装饰器 def __call__(self, func): print 'im Describer call' self._func = func return self def __get__(self, instance, owner): self._func(instance) instance.foo2() return 123 class Foo(object): def __init__(self): pass @Describer() def foo(self): print 'im Foo instance foo' def foo2(self): print 'im Foo instance foo2' f = Foo() # 注意,因为使用了描述符,所以类方法会被封装在描述符中,而这个方法会被描述符作为属性返回 # 所以foo作为描述符的属性方法存在 print f.foo
里面有有两块需要注意
1.1 __call__ 方法的返回值是Describer的对象obj。所以被装饰的函数都属于描述符的属性方法
1.2 这种装饰器+描述符的方式可以change自己想要change的方法
当然也可以使用静态方法或者类方法
class Describer(object): def __init__(self, name): self.name = name def __call__(self, func): # func 是 Foo().foo print 'im Describer call' def inner(foo_self, *args): # foo_self是Foo()对象 print foo_self.name return func(foo_self, *args) return inner class Foo(object): def __init__(self): self.name = 'www' @Describer('zhn') # 相当于 temp = Describer(__init__); inner = temp__call__(foo); func_result = inner(foo_self, *args) def foo(self): return 'im Foo instance foo' f = Foo() print f.foo() # out # im Describer call # www # im Foo instance foo
使用类装饰器会让显得更具有封装性和丰富性