从源码或者某处找出比较实用的写法

该文章持续跟新,看见好的写法就往上放

  1 __call__装饰器+描述符

  2 使用__call__方法将类定义为装饰器

1 __call__装饰器+描述符  

灵感来自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的方法

2 使用 __call__ 方法将类定义为装饰器  

当然也可以使用静态方法或者类方法

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

使用类装饰器会让显得更具有封装性和丰富性

原文地址:https://www.cnblogs.com/fuzzier/p/7850657.html