Python decorator code essence

# _*_ coding: utf-8 _*_

"""
python_decorator.py by xianhu
"""

import functools


# 构建不带参数的装饰器
def logging(func):
    @functools.wraps(func)
    def decorator(*args, **kwargs):
        print("%s called" % func.__name__)
        result = func(*args, **kwargs)
        print("%s end" % func.__name__)
        return result
    return decorator


# 使用装饰器
@logging
def test01(a, b):
    print("in function test01, a=%s, b=%s" % (a, b))
    return 1


# 使用装饰器
@logging
def test02(a, b, c=1):
    print("in function test02, a=%s, b=%s, c=%s" % (a, b, c))
    return 1


# 构建带参数的装饰器
def params_chack(*types, **kwtypes):
    def _outer(func):
        @functools.wraps(func)
        def _inner(*args, **kwargs):
            result = [isinstance(_param, _type) for _param, _type in zip(args, types)]
            assert all(result), "params_chack: invalid parameters"
            result = [isinstance(kwargs[_param], kwtypes[_param]) for _param in kwargs if _param in kwtypes]
            assert all(result), "params_chack: invalid parameters"
            return func(*args, **kwargs)
        return _inner
    return _outer


# 使用装饰器
@params_chack(int, (list, tuple))
def test03(a, b):
    print("in function test03, a=%s, b=%s" % (a, b))
    return 1


# 使用装饰器
@params_chack(int, str, c=(int, str))
def test04(a, b, c):
    print("in function test04, a=%s, b=%s, c=%s" % (a, b, c))
    return 1


# 在类的成员方法中使用装饰器
class ATest(object):
    @params_chack(object, int, str)
    def test(self, a, b):
        print("in function test of ATest, a=%s, b=%s" % (a, b))
        return 1


# 同时使用多个装饰器
@logging
@params_chack(int, str, (list, tuple))
def test05(a, b, c):
    print("in function test05, a=%s, b=%s, c=%s" % (a, b, c))
    return 1


# 构建不带参数的装饰器类
class Decorator(object):

    def __init__(self, func):
        self.func = func
        return

    def __call__(self, *args, **kwargs):
        print("%s called" % self.func.__name__)
        result = self.func(*args, **kwargs)
        print("%s end" % self.func.__name__)
        return result


# 使用装饰器
@Decorator
def test06(a, b, c):
    print("in function test06, a=%s, b=%s, c=%s" % (a, b, c))
    return 1


# 构建带参数的装饰器类
class ParamCheck(object):

    def __init__(self, *types, **kwtypes):
        self.types = types
        self.kwtypes = kwtypes
        return

    def __call__(self, func):
        @functools.wraps(func)
        def _inner(*args, **kwargs):
            result = [isinstance(_param, _type) for _param, _type in zip(args, self.types)]
            assert all(result), "params_chack: invalid parameters"
            result = [isinstance(kwargs[_param], self.kwtypes[_param]) for _param in kwargs if _param in self.kwtypes]
            assert all(result), "params_chack: invalid parameters"
            return func(*args, **kwargs)
        return _inner


# 使用装饰器
@ParamCheck(int, str, (list, tuple))
def test07(a, b, c):
    print("in function test06, a=%s, b=%s, c=%s" % (a, b, c))
    return 1


# 装饰器实例: 函数缓存
def funccache(func):
    cache = {}

    @functools.wraps(func)
    def _inner(*args):
        if args not in cache:
            cache[args] = func(*args)
        return cache[args]
    return _inner


# 使用装饰器
@funccache
def test08(a, b, c):
    # 其他复杂或耗时计算
    return a + b + c


# 使用Python自带的装饰器 @property
class Person(object):

    def __init__(self):
        self._name = None
        return

    def get_name(self):
        print("get_name")
        return self._name

    def set_name(self, name):
        print("set_name")
        self._name = name
        return

    name = property(fget=get_name, fset=set_name, doc="person name")


# 使用Python自带的装饰器 @property
class People(object):

    def __init__(self):
        self._name = None
        self._age = None
        return

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, name):
        self._name = name
        return

    @property
    def age(self):
        return self._age

    @age.setter
    def age(self, age):
        assert 0 < age < 120
        self._age = age
        return


# 类静态方法和类方法
class A(object):
    var = 1

    def func(self):
        print(self.var)
        return

    @staticmethod
    def static_func():
        print(A.var)
        return

    @classmethod
    def class_func(cls):
        print(cls.var)
        cls().func()
        return

Guess you like

Origin blog.csdn.net/liuqinhou/article/details/129894190