• python 类的装饰器


    我们知道,在不改变原有代码的基础上,我们可以使用装饰器为函数添加新的功能。同理,一切皆对象,我们也可以使用装饰器为类添加类属性。what?

      

    def deco(obj):
        obj.x = 1
        obj.y = 2
        return obj
    
    
    @deco  # Foo = deco(Foo)
    class Foo:
        pass
    
    
    print(Foo.__dict__)

    上述的代码为Foo属性字典添加了x和y属性,但如果想添加'name' = 'harden'呢,这需要更灵活的定义了。so

    def deco(**kwargs):
    
        def wrapper(obj):
            for k, v in kwargs.items():
                setattr(obj, k, v)
            return obj
        return wrapper
    
    
    @deco(x=1, y=2)
    class Foo:
        pass
    
    print(Foo.__dict__)
    {'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None, 'x': 1, 'y': 2}

    我们再定义类Bar,

    @deco(name='curry')
    class Bar:
        pass

    name属性也可以添加进去

    再来个升级版,利用数据描述符和类的装饰器为类属性限定数据类型

    我们知道,在不改变原有代码的基础上,我们可以使用装饰器为函数添加新的功能。同理,一切皆对象,我们也可以使用装饰器为类添加类属性。what?
    
      
    
    def deco(obj):
        obj.x = 1
        obj.y = 2
        return obj
    
    
    @deco  # Foo = deco(Foo)
    class Foo:
        pass
    
    
    print(Foo.__dict__)
    上述的代码为Foo属性字典添加了x和y属性,但如果想添加'name' = 'harden'呢,这需要更灵活的定义了。so
    
    def deco(**kwargs):
    
        def wrapper(obj):
            for k, v in kwargs.items():
                setattr(obj, k, v)
            return obj
        return wrapper
    
    
    @deco(x=1, y=2)
    class Foo:
        pass
    
    print(Foo.__dict__)
    {'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None, 'x': 1, 'y': 2}
    我们再定义类Bar,
    
    @deco(name='curry')
    class Bar:
        pass
    name属性也可以添加进去
    
    再来个升级版,利用数据描述符和类的装饰器为类属性限定数据类型
    
    #数据描述符,代理另一个新式类的属性
    class Typedef:
    
        def __init__(self, key, expected_type):
            self.key = key
            self.expected_type = expected_type
    
        def __get__(self, instance, owner):
            # print('exec __get__')
            # print(instance)
            # print(owner)
            return instance.__dict__[self.key]
    
        def __set__(self, instance, value):
            # print('exec __set__')
            if not isinstance(value, self.expected_type):
                raise TypeError
            instance.__dict__[self.key] = value
    
        def __delete__(self, instance):
            instance.__dict__.pop(self.key)
    
    
    def deco(**kwargs):
        def wrapper(obj):
            for k, v in kwargs.items():
           #为obj添加属性 如 name = Tpyedef('name', str)
                setattr(obj, k, Typedef(k, v))
            return obj
        return wrapper
    
    
    @deco(name=str, age=int, salary=float)  # =====》People= wrapper(People)
    class People:
    
        def __init__(self, name, age, salary):
            self.name = name
            self.age = age
            self.salary = salary
    
    
    p1 = People('handen', 18, 111.11)
    print(p1.name)
    print(p1.__dict__)
  • 相关阅读:
    系统编程-进程-vfork使用、浅析
    C语言实现面向对象方法学的GLib、GObject-初体验
    技术储备--SPI接口硬件协议栈芯片W5500使用
    Linux板子与ubuntu交互,NFS配置
    开发板、windows、虚拟机互相ping通
    HTML 列表的使用
    锚链接的使用
    超链接的使用
    4.3 浏览器模拟--headers属性
    利用urllib下载图片
  • 原文地址:https://www.cnblogs.com/jeavy/p/10051889.html
Copyright © 2020-2023  润新知