• 特殊成员


    一、特殊成员补充:
    • 索引、切片
      • 当对象后面加小括号,自动执行call方法
      • 当对象后面加中括号,会自动执行 item相关方法
        1. __getitem__(self,item)    
        2. __setitem__(self, key, value)
        3. __delitem__(self, key)
    • 调用方式:
      • [item ] 索引:
        • 以“索引”方式进行方法调用,中括号中的item被当做一个str 类型
    class Class1:

    def __getitem__(self, item):
    print('getitem , get:{}, type:{}'.format(item, type(item)))

    def __setitem__(self, key, value):
    print('setitem , key:{}  value:{},  type:{},type:{}'.format(key, value, type(key), type(value)))

    def __delitem__(self, key):
    print('delitem,  key:{}, type:{}'.format(key, type(key)))

    # 实例化并调用
    obj = Class1()
    obj['test1']                 #“对象索引”,自动触发执行__getitem__()方法
    obj['test2'] = 'value2' #“对象索引”赋值,自动触发执行__setitem(key,value) 方法,并将索引的key和值value传给形参
    del obj['test3']           #    删除“对象索引”,自动触发执行 __delitem__(self,key) 方法,并自动将索引的key传递给形参
      • [star:stop:step] 切片:        
        • 以“切片”方式进行方法调用,中括号中的内容被当做一个slice对象,并将start,stop,step传递给slice的3个字段,slice.start ,slice.stop,slice.step
    class Class1:

    def __getitem__(self, item):
    print(item, type(item))
    print('item start:{}'.format(item.start))
    print('item stop:{}'.format(item.stop))
    print('item step:{}'.format(item.step))

    def __setitem__(self, key, value):
    print(key, type(key), value, type(value))
    print('key start:{}'.format(key.start))
    print('key stop:{}'.format(key.stop))
    print('key step:{}'.format(key.step))
    print('value:{}'.format(value))

    def __delitem__(self, key):
    print(key, type(key))
    print('key start:{}'.format(key.start))
    print('key stop:{}'.format(key.stop))
    print('key step:{}'.format(key.step))

    # 实例化并执行
    obj = Class1()
    obj[1:2:3]  # 对象切片,会自动执行__getitem__(self, item) 函数,并将[start:stop,step] 传递给 slice 对象
    obj[1:2:3] = [1, 2, 3, 4, 5] # 切片赋值,会自动执行__setitem__(slef,key,value) 函数,并将 [start:stop,step] 传递给 slice 对象 key; 值赋给 value
    del obj[1:2:3]  # 切片删除,会自动执行__delitem__(self, key) 函数,并将[start:stop,step] 传递给 slice 对象
      • 有序字典:
        • 字典没有提供有序的功能,需要在字典类的基础上进行操作
        • 实际是字典的key有序,即将key放在列表中
      class Mydic(dict):
      def __init__(self):
      self.lst = []
      super(Mydic, self).__init__()

      def __setitem__(self, key, value):
      self.lst.append(key)
      super(Mydic, self).__setitem__(key, value)


      def __str__(self):
      temp_lst = []
      for x in self.lst:
      dic_value = super(Mydic, self).get(x)
      temp_lst.append('{}:{}'.format(x, dic_value))
      f_dic = '{' + ','.join(temp_lst) + '}'
      return f_dic   # __str__ 方法 return什么值,就输出什么值

      # 实例化并调用
      obj = Mydict()
      obj['k1'] = 123
      obj['k2'] = 456
      obj['k3'] = 789
      obj['k4'] = ‘abc’
      print(obj)   # 调用__str__ 方法,此时每次输出的都是有序字典

    • 迭代方法:
      • __iter__()   //一个方法要想能被迭代,就要实现这个方法,且该方法返回一个迭代对象
        • 可迭代对象:
          • 一个实现了“迭代协议”的对象,迭代协议如下:
            • __iter__() :返回iterator对象本身
            • __next__(): 每当该函数被调用,返回(return)一个值,并直到StopIteration 异常时停止
        • python 的 for 循环遍历过程:
          1. 先调用__iter__()方法,来获得迭代器
          2. 调用迭代器的 next()方法,获得数据,直到抛出StopIteration异常
      • example:
    class Class1:
    def __init__(self, ):
    self.number = 0

    def __iter__(self):
    return self    # 拥有__iter__方法的对象,就为迭代器,所以自定义迭代器通常返回对象实例自己

    def __next__(self):
    if self.number >= 10:
    raise StopIteration
    else:
    self.number += 2
    return self.number
    # 实例化并执行
    obj = Class1()
    for x in obj:   
    print(x)

    二、面向对象其它:

    • isinstance(obj,Class1) 
      • 查看对象是否为class1的实例,或其所创建类的父类,当class为obj的父类,或class为obj的父类的父类时,返回True
    • issubclass(class2,Class1)  
      • 返回布尔值,查看class2是否为class1的子类
    • super(myclass, self).function(args)
      • 调用并执行 myclass父类中的function方法
    # 经常用于执行父类中与子类同名的方法:
    class C1:
    def f1(self):
    print('c1.f1')

    class C2(C1):
    def f1(self):
    # 表示主动执行父类中的f1方法
    super(C2,self).f1()  # 第一中方法
    print('c2.f1')

    obj = C2()


     

    二、扩展:旧框架新增功能

    • 不用装饰器原因:装饰器需要在函数上方加@,即会改动源代码
    • 使用super:
      • 业务场景:
    --------------------------------公司代码场景
    # 老员工NB代码核心逻辑   
       
    vim backend/commons
    ......nb的代码,其中有个Foo类

    # 程序配置文件
    vim settings.py
    Path = 'bakend.commons' // 模块所在路径
    ClassName = 'Foo'          //所需要的目标类

    # 老员工NB代码入口
    vim index.py       
    from settings import Path           类所在模块的路径
    from settings import ClassName    所需要调用的类名

    def excute():
    module = __import(Path,fromlist=True)   # 从路径中找到目标模块
    cls = getattr(commons, ClassName)   #  从目标模块中找到目标类
    obj = cls()
    obj.func1()                # 领导要求对该功能进行封装 ,该功能存在于核心逻辑中,核心逻辑文件不能修改,该入口文件也不能改,总之什么都不能改

    if __nam__ == '__main__':
    excute()
      • 更改:
        • 思想:
          • 通过继承的方式。来实现在老代码中添加功能   
          • 即只需要继承老员工的类,对目标方法进行修改后,更改配置文件类的指向即可    
        • 图示

        • 过程:
    # 封装功能的文件
    vim  lib.py       
    from backend.commons import Foo  # 导入要被封装的类

    class my_class(Foo):         # 新建一个类,并继承老员工的类
    def func1(self):
    print('before')
    super(my_class, self).func1()     //执行老员工Foo类中的原本的功能
    print('after')  // 新增功能
    # 修改配置文件
    vim setting.py
    Path = 'lib'
    ClassName = 'my_class'





















  • 相关阅读:
    第 6 章 Cinder
    第 6 章 Cinder
    第 6 章 Cinder
    第 6 章 Cinder
    第 6 章 Cinder
    第 6 章 Cinder
    第 6 章 Cinder
    第 6 章 Cinder
    第 6 章 Cinder
    第 6 章 Cinder
  • 原文地址:https://www.cnblogs.com/qiaogy/p/5818668.html
Copyright © 2020-2023  润新知