python学习day22 面向对象(四) 约束&反射

时间:2022-12-15 13:21:46

1.栈与队列

  • 栈:类似弹夹,先进后出
  • 队列:类似水管,先进先出
class Stack(object):
    """
    先进后出
    """
    def __init__(self):
        self.data_list=[]
        
    def push(self,val):
        """
        向栈中压入一个数据(入栈)
        """
        self.data_list.append(val)
        
    def pop(self):
        """
        从栈中拿走一个数据(出栈)
        """
        return self.data_list.pop()

2.可迭代对象

  • 表象:可以被for循环的对象就是可迭代对象

  • 在类中实现__iter__方法且返回一个迭代器(生成器)

    class Foo:
        def __iter__(self):
            return iter([1,2,3,4])
    obj = Foo()
    
    class Foo:
        def __iter__(self):
            yield 1
            yield 2
            yield 3
    
    obj = Foo()                                                               

3.约束

  • 约束子类内必须使用方法,不然主动异常

    class BaseMessage(object):
        def send(self,a1):
            raise NotImplementedError('字类中必须有send方法')
    
    class Msg(BaseMessage):
        def send(self):
            pass
    
    class Email(BaseMessage):
        def send(self):
            pass
    
    class Wechat(BaseMessage):
        def send(self):
            pass
    
    class DingDing(BaseMessage):
        def send(self):
            print('钉钉')
    
    obj = Email()
    obj.send()

4.反射 * * * * *

  • python一切皆对象,所以想要通过字符串的形式操作内部成员都可以通过反射去完成操作.

  • py文件 包 类 对象...

  • 反射:根据字符串的形式去某个对象操作对象的成员.

    • getattr(对象名,"方法名")

      • 根据字符串的形式去某个对象中获取对象的成员.
      • attribute属性
      class Foo(object):
          def __init__(self,name):
            self.name = name
          def login(self):
            pass
      obj = Foo('alex')
      
      # 获取变量
      v1 = getattr(obj,'name')
      # 获取方法
      method_name = getattr(obj,'login')
      method_name()
    • setattr(对象名称,"变量",值 )

      • 根据字符串的形式去某个对象中设置成员.
      class Foo:
        pass
      obj = Foo()
        obj.k1 = 999
      setattr(obj,'k1',123) # obj.k1 = 123
      
        print(obj.k1)
    • hasattr(对象名称,"方法名")

      • 根据字符串的形式去某个对象中判断是否含有某成员.返回布尔类型
        class Foo:
            pass
      
        obj = Foo()
        obj.k1 = 999
        hasattr(obj,'k1')
        print(obj.k1)
    • delattr(对象,"方法名")

    • 根据字符串的形式去某个对象中删除某成员.

    class Foo:
        pass
    
    obj = Foo()
    obj.k1 = 999
    delattr(obj,'k1')
    print(obj.k1)

5.补充:模块importlib

  • importlib 用字符串的形式导入模块

    模块 = importlib.import_module('utils.redis')
    • 示例:
    import importlib
    
    #用字符串的模式导入模块
    redis = importlib.import_module("utils.redis")
    #用字符串的形式去对象(模块)找到他的成员
    getattr(redis,"func")()
    
    self.MIDDLEWARE_CLASSES = [
                'utils.session.SessionMiddleware',
                'utils.auth.AuthMiddleware',
                'utils.csrf.CrsfMiddleware',
            ]
    for mes in self.MIDDLEWARE_CLASSES:
        module_path,class_name=mes.rsplit('.',maxsplit=1)       #切割路径和类名
        module_object = importlib.import_module(module_path)    #插入模块-字符串操作
        cla=getattr(module_object,class_name)        #根据模块对象找到类名(字符串操作-反射)
        obj = cla()      #实例化对象
      obj.process()      #运行内部函数process