天天看點

面向對象裡的限制與反射應用

限制

  • 限制子類内必須使用方法,不然主動異常
    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()
               

反射

  • 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)
               

子產品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