美文网首页
8.自省反射 和 类内置方法

8.自省反射 和 类内置方法

作者: 芝麻酱的简书 | 来源:发表于2018-08-17 11:54 被阅读18次

    反射四个方法的使用:

    hasattr(result, "name")
    
    getattr(result, "name", "bill")
    
    setattr(result, "name", "bill")
    
    delattr(result, "name")
    

    反射的用处:

    1. 动态增加属性,包括数据属性和方法属性
    # 声明方
    class Dad(metaclass=abc.ABCMeta):
        def __init__(self, name):
            self.name = name
    
    
    
    # 模拟外部使用方
    
    dad1 = Dad("bill")
    
    if hasattr(dad1, "eatFood"):
        eatFood_func = getattr(dad1,"eatFood")
        eatFood_func()
    
    else:
        pass
    
    1. 动态导入模块
      方式1:__import__("sys")
      方式2:
    import importlib
    
    m = importlib.import_module("m1.t")
    m.test()
    

    使用super继承包装父类方法:

    # 继承自系统类list  重写系统类的方法
    class NewList(list):
    
        def append(self, obj):
            if type(obj) is str:
                super().append(obj)
    
    
    list1 = NewList()
    list1.append("adf") # 添加成功
    list1.append(123)   # 添加失败
    

    类内置方法:

    🎈类内置__getattribute__方法:
    访问类属性,就是访问__getattribute__方法,如果没有找到访问的属性,则抛出异常,执行__getattr__方法

        def __getattribute__(self, item):
            raise AttributeError("抛出异常 去执行__getattr__")
    
        def __getattr__(self, item):
            pass
    

    🎈类内置__getattr__方法:
    访问类属性的时候,如果有该属性,则不触发__getattr__方法,如果没有该属性,则触发__getattr__方法

    🎈类内置__delattr__方法:
    只要访问属性就会触发

    🎈类内置__setattr__方法只要访问属性就会触发,可以使用设置属性字典__dict__的方法来防止递归死循环

    🎈类内置__getitem__ __setitem__等方法,是通过字典resuslt["name"]这种方式取、设置、删除属性等操作触发

    🎈使用__str__来改变对象的打印信息:

    class Foo:
        def __str__(self):
            return "这是"
    
    print(Foo())
    

    🎈使用__repr__来改变对象在解释器中的打印信息:
    优先找__str__,没有会找__repr__

    🎈使用__format__来格式化定制打印信息

    🎈使用__slots__来节省内存,只能使用声明的属性

    class Foo:
        __slots__ = ["name", "age"]
    

    🎈使用__module____class__查看对象所在的模块和类

    🎈__del__析构方法

    🎈使用__call__定义call方法Foo()


    迭代器:

    🎈使用__next____iter__实现迭代器协议

    迭代器协议:对象必须提供一个next方法,执行该方法返回迭代中的下一项,或者 到最后一项后抛出StopIteration异常,以终止迭代。

    可迭代对象:实现了迭代器协议的对象(如何实现:对象内部定义了一个__iter__方法)

    调用for in循环,实际就是调用对象的iter(obj)方法,也即obj.__iter__方法,装换成迭代器对象,然后执行对象的__next__方法。

    对于一个自定义类,想要实现迭代器协议,可以重写如下方法:

    def __iter__(self):
          return self
    
    def __next__(self):
          if xxx:
                raise StopIteration("终止")
          return xxx
    

    访问优先级:
    1. 类属性
    2. 数据描述符
    3. 实例属性
    4. 非数据描述符
    5. 找不到属性触发__getattr__()
    


    上下文管理协议with as

    使用__enter____exit__方法
    如果执行with as过程中程序异常,会直接执行__exit__并抛出异常,如果__exit__中返回True,则会忽略掉异常继续执行

    相关文章

      网友评论

          本文标题:8.自省反射 和 类内置方法

          本文链接:https://www.haomeiwen.com/subject/gqpzbftx.html