反射实操与面向对象双下方法

反射实操

利用面向对象的反射编写系统终端

 反射提供了一种不考虑代码,对数据和功能进行操作的方式

      class WinCmd(object):  # 定义一个WinCmd的类
          def ls(self):
              print('windows ls命令')

          def dir(self):
              print('windows dir命令')

          def cd(self):
              print('windows cd命令')


      class Linux(object):  # # 定义一个Linux的类
          def ls(self):
              print('linux ls命令')

          def dir(self):
              print('linux dir命令')

          def cd(self):
              print('linux cd命令')


      obj1 = WinCmd()  # 生成对象
      print(obj1)  # <__main__.WinCmd object at 0x0000017B0E7A23C8>
      obj2 = Linux()  # 生成对象
      print(obj2)  # <__main__.Linux object at 0x0000017B0E7A2470>


      def run(obj):
          while True:
              cmd = input('cmd order>>>: ').strip()  # 获取用户命令
              if hasattr(obj, cmd):  # 如果对象的名称空间有该字符串所对应的数据或者功能,结果为True
                  func_name = getattr(obj, cmd)  # 如果对象的名称空间有该字符串所对应的数据或者功能,取其对应的数据或者功能
                  func_name()
              else:
                  print('cmd order is not be found')


      run(obj1)  # 类似于win的cmd命令
      run(obj2)  # 类似linux的命令窗口

面向对象部分双下方法(内置方法)

 面向对象中有一些方法名字是类似于__……__的结构。这类方法也被人称为魔法方法。因为有些双下方法是不需要调用的,而是在特殊条件下自动触发的。比如__init__方法会在对象实例化的时候自动触发。

      class MyClass(object):
          person: True
          def __init__(self, name, age, gender):  # 对象实例化
              self.name = name
              self.age = age
              self.gender = gender

          def __str__(self):  # 对象展示的时候自动触发
              print('打印操作')
              return 'print'

          def __del__(self):  # 主动或者被动(执行结束,垃圾处理机制作用)删除对象的时候触发
              print('删除操作')
              pass

          def __getattr__(self, item):  # 获取数据或者功能,找不到时触发
              print('爱而不得')
              pass

          def __call__(self, *args, **kwargs):  # 对象被加括号调用的时候触发
              print('调用对象')
              pass

          def __enter__(self):  # with方法操作对象时触发
              print('文件管理操作')
              pass

          def __exit__(self, exc_type, exc_val, exc_tb):  # 结束操作对象时触发
              print('文件管理操作结束')
              pass

          def __getattribute__(self, item):  # 查找数据或功能时触发,无论能不能找到
              print('大胆爱')
              pass

          '''在__getattr__方法和__getattribute__方法同时存在时,后者会顶替前者执行作用,前者不执行'''

      obj1 = MyClass('oliver', 25, 'male')

      print(obj1)
      '''释放__getattr__方法,注掉__getattribute__方法'''
      obj1.name  # 能获取到
      obj1.salary  # 获取不到  爱而不得  (__gertattr__)

      '''释放__getattribute__方法,注掉__getattr__方法'''
      obj1.name  # 大胆爱
      obj1.salary  # 大胆爱

      '''释放__getattribute__方法,__getattr__方法'''
      obj1.name  # 大胆爱
      obj1.salary  # 大胆爱

      '''在__getattr__方法和__getattribute__方法同时存在时,后者会顶替前者执行作用,前者不执行'''

      obj1()  # 调用对象

      with obj1 as f:
          print('进行文件操作')  # 文件管理操作(__enter__)  进行文件操作  文件管理操作结束(__exit__)

更多方法:面向对象更多双下方法

问题处理

问题一: 使字典具备句点符取值的功能

      class MyDict(dict):
          def __getattr__(self, item):  # 取对象中的名字是'item'的数据或者方法
              return self.get(item)  # 获得该名字所对应的数据或者功能名

          def __setattr__(self, key, value):  # 在名称空间中添加数据
              self[key] = value  # 以键值对的方式添加


      obj1 = MyDict('oliver', 25)
      print(obj1)  # {'name': 'oliver', 'age': 25}
      print(obj1.name)  # oliver
      print(obj1.age)  # 25

      obj1.gender = 'male'  # 通过点的方式对对象的名称空间进行操作,添加数据
      print(obj1)  # {'name': 'oliver', 'age': 25, 'gender': 'male'}
      print(obj1.salary)  # None

问题二:代码补全问题

'''
题目:
        class Context:
            pass

        with Context() as ctx:
            ctx.do_something()
'''

'''
解决步骤:
      分析:
              类 Context -----> Context():产生对象 -----> with 操作 Context():需要有 __enter__ 和__exit__
              -----> ctx.do_something() 对象用点的方式访问do_something,且do_something加了括号,所以对象有
              do_something方法
'''

      class Context:
          def __enter__(self):
              return self

          def __exit__(self, exc_type, exc_val, exc_tb):
              return 123

          def do_something(self):
              print('代码已补全')


      with Context() as ctx:
          ctx.do_something()  # 代码已补全
posted @ 2022-04-11 22:14  Oliver-Chance  阅读(27)  评论(0编辑  收藏  举报