zoukankan      html  css  js  c++  java
  • 反射

    1.反射

    反射指的是一个对象应该具备可以检测,修改,增加自身属性的能力。反射可以通过字符串操作属性,共涉及到四个属性,这四个函数就是普通的内置函数,没有双下划线,与print等等没有区别。

    # hasattr  getattr  setattr  delattr的用法
    class Person:
        def __init__(self,name,age,gender):
            self.name =name
            self.age = age
            self.gender = gender
    
    p = Person('li',18,',man')
    # print(p.age)      # >>>:18
    # print(hasattr(p,'name'))    # >>>:True 判断某个对象是否存在某个属性
    if hasattr(p,'name'):
        print(getattr(p,'name',None))
    #从对象中取出属性,第三个值为默认位,当属性不存在时就返回出默认值
    
    #为对象添加新的属性
    setattr(p,"id",'91')
    print(p.id)
    
    # 从对象里面删除属性
    delattr(p,"id")
    delattr(p,'age')
    print(p.__dict__)#里面中的id,age属性被删除了
    # >>>:{'name': 'li', 'gender': ',man'}

      使用场景:反射其实就是对属性的增删改查,如果直接使用__dict__来操作,语句繁琐,不好理解。另外一个最主要的问题是,如果对象不是自己写的,而是第三方提供的,我就必须判断这个对象是否满足我需要的属性和方法。

    2.元类 metaclass

    元类是用来创建类的类,把要创建的类看成是元类的对象。对象是通过是通过实例化产生的,如果类也是对象的话,必然类对象也是由另一个类实例化产生的。默认情况下所有类的元类都是type。

    只要继承了type,那么这个类就变成了一个元类。

    #自己直接定义的一个元类
    class
    MyType(type): def __init__(self,class_name,bases,dict): super().__init__(class_name,bases,dict) print(class_name,bases,dict) if not class_name.istitle(): raise Exception("类名格式不对") class Duck(metaclass=MyType): # 为duck类指定了元类为MyType pass
    >>>:Duck () {'__module__': '__main__', '__qualname__': 'Duck'}

    3.元类中的call方法

      当你调用累对象时会自动调用元类中的__call__方法,并将这个类本身作为第一个参数传入,以及后面的一堆差数。当覆盖元类中的call之后,这个类就无法产生对象,必须调用super().__call__来完成对象的创建。

      使用场景:当你想要控制对象的创建过程时,就覆盖call方法;当你想要控制类的创建过程时,就覆盖init方法。

    # 实现将对象的所有属性名称转大写
    class MyType(type):
        def __call__(self, *args, **kwargs):
            new_args = []
            for a in args:
                new_args.append(a.upper())
    
            print(new_args)
            print(kwargs)
            return super().__call__(*new_args,**kwargs)
    
    
    class Person(metaclass=MyType):
        def __init__(self,name,gender):
            self.name = name
            self.gender = gender
    
    p = Person("jack""woman")
    print(p.name)#>>>:JACK
    print(p.gender)#>>>:WOMAN
    注意:一旦覆盖了call必须要调用父类的call方法来产生对象并返回这个对象。
  • 相关阅读:
    白名单执行payload之rundll32
    java.lang.NoClassDefFoundError: com/fasterxml/jackson/databind/JsonNode
    Redis key过期监听
    Kafka拦截器
    常用工具类
    Redis Pipelining
    Redis 发布订阅(Pub/Sub)
    Redis Stream
    模拟Spring自实现监听器
    Jackson
  • 原文地址:https://www.cnblogs.com/blue-tea/p/11272230.html
Copyright © 2011-2022 走看看