天天看点

一个例子理解 Python 内置装饰器及 cached_property

# coding=utf-8
from functools import cached_property


class Test:
    c = 3

    def __init__(self, *args, **kwargs):
        self.a = 1

    @property
    def aaa(self):
        print("I'm in aaa")
        # 可以通过 self.a 或者 self.c 访问 a 和 c 变量
        return "aaa"

    @cached_property
    def bbb(self):
        print("I'm in bbb")
        return "bbb"

    @staticmethod
    def fun1():
        # 无法访问 a 或者 c 变量
        print(f"staticmethod{1}")

    @classmethod
    def fun2(cls):
        # 可以访问 cls.c 访问 c 变量,无法访问 a 变量
        b = cls.c + 1
        print(f"classmethod{b}")


if __name__ == '__main__':
    t = Test()
    # @property 装饰器可以直接通过访问变量的方式访问方法, 每次调用都会执行一次。
    print(t.aaa)
    print(t.aaa)
    # @cached_property 在 property 的基础上加强了,可以把值缓存起来,只执行一次。 执行一次后会缓存在 __dict__ 变量里
    print(t.__dict__)
    print(t.bbb)
    print(t.bbb)
    print(t.__dict__)
    # staticmethod 是相当于把函数放到了类里面,不能访问类的所有东西。可通过对象或类名直接访问
    t.fun1()
    Test.fun1()
    # classmethod 类方法,不能访问实例变量,只能访问类变量和类方法。可通过对象或类名直接访问
    t.fun2()
    Test.fun2()
           

输出:

I'm in aaa
aaa
I'm in aaa
aaa
{'a': 1}
I'm in bbb
bbb
bbb
{'a': 1, 'bbb': 'bbb'}
staticmethod1
staticmethod1
classmethod4
classmethod4
           

总结:

  • @property

    装饰器可以直接通过访问变量的方式访问方法, 每次调用都会执行一次。
  • @cached_property

    在 property 的基础上加强了,可以把值缓存起来,只执行一次。 执行一次后会缓存在

    __dict__

    变量里
  • @staticmethod

    是相当于把函数放到了类里面,不能访问类的所有东西。可通过对象或类名直接访问
  • @classmethod

    类方法,不能访问实例变量,只能访问类变量和类方法。可通过对象或类名直接访问
  • staticmethod vs classmethod : staticmethod 没法访问类的所有东西,classmethod 可以访问类变量及类方法。