实现Python静态装饰器、类装饰器、Property装饰器

2018-01-23  本文已影响25人  loveroot

from functools import partial, wraps

class Staticmethod(object):
    def __init__(self, function):
        wraps(function)(self)

    def __get__(self, instance, owner):
        return partial(self.__wrapped__)


class ClassMethod(object):
    def __init__(self, func):
        wraps(func)(self)

    def __get__(self, instance, owner):
        return partial(self.__wrapped__, owner)


class Property(object):
    def __init__(self, fget=None, fset=None, fdel=None):
        self.fget = fget
        self.fset = fset
        self.fdel = fdel

    def __get__(self, instance, owner):
        if instance is None:
            return self
        if not callable(self.fget):
            raise AttributeError('not callable')
        return self.fget(instance)

    def __set__(self, instance, value):
        if instance is None:
            return self
        if not callable(self.fset):
            raise AttributeError('not callable')
        print('call me')
        return self.fset(instance, value)

    def setter(self, fset):
        self.fset = fset
        return self

    def deleter(self, fdel):
        self.fdel = fdel


class Hello(object):
    def __init__(self, x):
        self.x = x

    @Staticmethod
    def hello(*args, **kwargs):
        print('static method')

    def bar(*args, **kwargs):
        print(args)

    @staticmethod
    def abc(*args, **kwargs):
        print(args)
        print(kwargs)
        print('abc')

    @classmethod
    def foo(cls):
        print(cls)
        print('class method')

    @ClassMethod
    def zzz(klass, *args, **kwargs):
        print(klass)
        print(args)
        print(kwargs)

    @Property
    def yyy(self):
        print('yyy', self.x)

    @yyy.setter
    def yyy(self, value):
        self.x = value
        print(self.x)

    # abc = yyy.setter(abc)


    # yyy = Property(fget=yyy,fset=None,fdel=None)

h = Hello(123)
h.hello()
h.abc(1,2, a='a', b='b')
h.foo()
h.bar(1,2,3)
h.zzz(12,3, test='test')
h.yyy
h.yyy = 10
h.yyy
============output==========
static method
(1, 2)
{'a': 'a', 'b': 'b'}
abc
<class '__main__.Hello'>
class method
(<__main__.Hello object at 0x054E6F70>, 1, 2, 3)
<class '__main__.Hello'>
(12, 3)
{'test': 'test'}
yyy 123
call me
call------------
10
yyy 10
上一篇下一篇

猜你喜欢

热点阅读