Appearance
什么是装饰器?装饰器也是一种函数,可以接收函数作为参数,可以返回函数,接收一个函数,内部对其处理返回一个新函数,动态增强函数功能。
例如将c函数在a函数中执行,在a函数中可以选择执行或不执行c函数,也可以对c函数的结果进行二次加工。
装饰器的定义 
这里以一个案例来描述装饰器是如何定义的,首先看下面代码:
python
def test(data):
    return data需求如下:如果data='ok'则返回result is {data},如果不等于ok则返回result is failed:{data},来看装饰器的定义。
python
def check_str(func):
    def inner(*args, **kwargs):
        result = func(*args, **kwargs)
        if result == 'ok':
            return f'result is %s' % result
        else:
            return f'result is failed:%s' % result
    return inner装饰器的使用 
上面我们编写了一个装饰器,使用方法也很简单,在方法上加上@装饰器名称即可,代码如下所示:
python
def check_str(func):
    def inner(*args, **kwargs):
        result = func(*args, **kwargs)
        if result == 'ok':
            return f'result is %s' % result
        else:
            return f'result is failed:%s' % result
    return inner
@check_str
def test(data):
    return data
if __name__ == '__main__':
    result = test('no')
    print(result)类中常用装饰器 
classmethod 
我的理解是,java类中有static静态方法可以直接通过类名.方法调用,而classmethod和java中的静态方法很类似。
在Python中使用@classmethod装饰后cls替代普通类函数中的self变为cls,代表操作的是类。
python
class Test(object):
    @classmethod        # self变为cls
    def add(cls, a, b):
        return a + b
print(Test.add(12, 15))  # 直接调用即可说明:@classmethod装饰的函数无法调用普通函数,但普通函数可以调用@classmethod装饰的函数。
staticmethod 
将类函数可以不经过实例化而直接被调用,被该装饰器调用的函数不许传递self或cls参数,且无法再该函数内调用其它类函数或类变量。
python
class Test(object):
    @staticmethod        # 注意没有cls或self参数
    def add(a, b):
        return a + b
print(Test.add(12, 15))  # 直接调用即可和@classmethod的区别是,@staticmethod没有cls或self参数,因此它没有办法调用类中的其他方法,常在工具类中使用。
property 
当某个函数不需要传参,直接调用时,使用property装饰后,使用时可以省略括号,使用方法如下所示。
python
class Test(object):
    @property
    def hello(self):
        print("你好,我不需要参数,你可以像调用变量一样调用我")
test = Test()
test.hello         # 和调用变量一样调用函数,不需要加括号它还有一个有趣的写法,可以像变量一样直接赋值。
python
class Test(object):
    __name = None
    @property
    def hello(self):
        print("你好,我不需要参数,你可以像调用变量一样调用我")
        return self.__name
    @hello.setter                       # 方法名.setter
    def hello(self, value):
        self.__name = value
        print(f"你好,{self.__name}")
        return self.__name
test = Test()
test.hello = '张三'
print(test.hello)运行效果如下所示:
python
你好,张三
你好,我不需要参数,你可以像调用变量一样调用我
张三