• 装饰器


    property:    -- 将装饰过的函数(方法)变成类属性,这样的属性需要通过  -  @函数(方法).setter 才能够直接修改这个属性

    class A:
        @property                              # 将fun函数变成了类的属性
        def fun(self):    # 这儿只能有self参数
            return self._a
    @fun.setter # 这个属性需要被setter才能直接修改属性值 def fun(self, n): self._a = n

     staticmethod: 将类的方法变成静态方法  -- 将类中的函数参数self 变成普通参数

    应用场景:当把一个模块导入时,需要用到模块中的某个类和某个函数  from module import cls, fun   这样使用比较繁琐

    可以将fun写进cls类中,加上staticmethod装饰器,就能通过cls.fun(argv) 调用,而又不会影响fun的功能

    class A:
        @staticmethod
        def fun(self):   # 这儿self不在是实例化属性,变成普通参数了
            print(self)
    
    a = A()
    a.fun(2)   # 2被self接收

    classmethod: 类装饰器   -- 将类本身当作参数传入函数中

    class B:
        @classmethod
        def fun(cls):      # cls = B本身
            pass              

    自己构建的装饰器

    import functools
    
    
    def log(fn):
        @functools.wraps(fn)    # 将fn的相关属性复制到wrap
        def wrap(*args, **kwargs):
            print(f"decorator {fn}")
            return fn(*args, **kwargs)
        print(f"wrap: {id(wrap)}")
        print(f"fn: {id(fn)}")
        return wrap
    
    @log
    def guai(x: int, y: int):
        print(x + y)
    
    guai(1,5)

    >>>
    wrap: 4328403560
    fn: 4328403424
    decorator <function guai at 0x101fe31e0>
    6

    类型装饰器

    def log(cls):
        class wraper:
            def __init__(self, *args, **kwargs):
                self.__dict__['inst'] = cls(*args, **kwargs)def __getattr__(self, item):
                print('here')
                print(item)
                return getattr(self.inst, item)
            def __setattr__(self, key, value):  # 拦截x.a的复制操作
                print('k:v', key, value)
                setattr(self.inst, key, value)   #拦截后储存到self.inst, 那么查询x.a也只能在self.inst中查到(通过__getattr__)
        return wraper
    
    @log
    class X: pass
    
    
    x = X()
    x.a = 100
    print(x.__dict__)
    print(x.a)

    >>>
    k:v a 100
    {'inst': <__main__.X object at 0x10cd704a8>}
    here
    a
    100

    装饰器的应用场景:辅助开发工具(调用跟踪,性能测试,内存检测等任务),类可以实现单例模式

    简单的统计调用次数:

    def log(fn):
        def counter(*args, **kwargs):
            counter.__count__ += 1
            return fn(*args, **kwargs)
    
        counter.__count__ = 0
        return counter
    
    @log
    def run():pass
    
    
    for i in range(4):
        run()
    print(f"调用次数{run.__count__}")
    >>>
    调用次数4

    属性管理:为目标添加额外的属性

    def add_somethings(cls):
        cls.something = 1
        cls.something1 = lambda x: [1,2,3,]
        return cls
    
    
    @add_somethings
    class A: pass
    
    
    print(A().something)
    print(A().something1())
    
    >>>
    1
    [1, 2, 3]
  • 相关阅读:
    悲悯心洞悉真相
    查看逍遥模拟器端口号
    delphi中Tstringlist分割字符串的用法
    delphi中httpencode使用注意事项
    DELPHI常用类型及定义单元
    左旋转字符串
    链表中倒数第k个节点
    二叉树镜像
    用两个栈实现队列
    从尾到头打印链表
  • 原文地址:https://www.cnblogs.com/tangpg/p/8653187.html
Copyright © 2020-2023  润新知