• 面向对象及命名空间


    面向对象

    类是相似功能的集合体

    对象

    对象是类中具体的个体体现

    实例化一个对象发生了三件事

    1. 在内存中创建一个对象空间
    2. 自动执行__init__方法,并且将对象地址传给self
    3. 执行__init__方法里面的代码,给对象空间封装其属性
    self

    位置参数,接收对象的地址

    空间结构

    对象查询属性:对象空间----类空间----父类

    类查询一个属性: 类空间---父类

    和局部与全局基本一致

    依旧是,对象只有使用类属性的权力,没有删除和修改的权力

    类与类之间的关系

    1. 依赖关系

      将一个类的类名或者对象传给另一个类的方法中

      ## 依赖关系
      class Elephant:
          def __init__(self,name):
              self.name = name
      
          def open(self,obj):
              print(f"{self.name}打开了{obj.name}冰箱")
              obj.open_door()
          def close(self,obj):
              print(f"{self.name}关闭了{obj.name}冰箱")
              obj.close_door()
      
      class Refrigerator:
          def __init__(self,name):
              self.name = name
      
          def open_door(self):
              print(f"{self.name}被打开了")
          def close_door(self):
              print(f"{self.name}被关闭了")
      
      
      e1 = Elephant('冰河')
      
      b1 = Refrigerator('火')
      
      e1.open(b1)
      e1.close(b1)
      
    2. 组合关系

      将一个类的对象封装到另一个类中对象的属性中

      ## 组合关系
      class Boy:
          def __init__(self,name):
              self.name = name
      
          def meet(self,girl=None):
              self.girl_friend = girl
      
          def have_dinner(self):
              print(f"{self.name}和{self.girl_friend.name}共进晚餐")
              self.girl_friend.shopping(self)
      
      class Girl:
          def __init__(self,name,age):
              self.name = name
              self.age = age
          def shopping(self,obj):
              print(f"{obj.name}和{self.name}一起去购物")
      
      yu = Boy('yu')
      en = Girl('en',22)
      
      yu.meet(en)
      
      yu.have_dinner()
      
      #en.shopping(yu)
      
      

      依赖加组合

      class GameRole:
          def __init__(self,name,hp,ad):
              self.name = name
              self.hp = hp
              self.ad = ad
          def equip_weapon(self,obj):
        		self.wea_attack = obj
          def attack(self,obj):
              obj.hp-=self.ad
              print (f"{self.name}攻击了{obj.name},{obj.name}还剩下{obj.hp}滴血")
      class Weapon:
          def __init__(self,name,att_value):
              self.name = name
              self.att_value = att_value
          def weapon(self,obj1,obj2):
              obj2.hp = obj2.hp-obj1.ad-self.att_value
              print (f"{obj1.name}使用{self.name}攻击了{obj2.name},{obj2.name}还剩下{obj2.hp}滴血")
      
      
      ys = GameRole('亚索',2000,200)
      jie = GameRole('劫',1800,220)
      wj = Weapon('无尽之刃',70)
      ys.equip_weapon(wj)
      ys.wea_attack.weapon(ys,jie)
      
    3. 继承关系

    继承

    1. 可以使用父类的所有方法和属性
    2. 继承的优点 : 节省代码,增强耦合性,使代码更规范
    3. 继承的缺点:耦合性过多,不利于代码的修改
    4. 单继承:只有一个父类
    5. 多继承:有多个父类,继承顺序,按照mro顺序(可以直接用类名点mro() )
    如计算merge( [E,O], [C,E,F,O], [C] )
    有三个列表 :  ①      ②          ③
    merge不为空,取出第一个列表列表①的表头E,进行判断                              
       各个列表的表尾分别是[O], [E,F,O],E在这些表尾的集合中,因而跳过当前当前列表
    取出列表②的表头C,进行判断
       C不在各个列表的集合中,因而将C拿出到merge外,并从所有表头删除
       merge( [E,O], [C,E,F,O], [C]) = [C] + merge( [E,O], [E,F,O] )
    进行下一次新的merge操作 ......
    ---------------------
    

    鸭子模型

    看起来像鸭子,就是鸭子

    两个毫无关系的类,只要功能相似,方法名一致,这样使用就会很方便

    方法的归一化

    方法的归一化和类的约束一起的例子

    class Pay:
        def pay(self,money):
            raise NotImplementedError('sb 重写我')
    
    class Qqpay(Pay):
        def pay(self,money):
            print(f'使用qq支付{money}')
    
    class Alipay(Pay):
        def pay(self,money):
            print(f'使用支付宝支付{money}')
    
    class Wechat(Pay):
        def fuqian(self,money):
            print(f"使用微信支付{money}")
    
        # def pay(self,money):
        #     print(f"使用微信支付{money}")
    
    
    def pay(obj,money):
        obj.pay(money)
    
    
    p1 = Alipay()
    p2 = Qqpay()
    p3 = Wechat()
    
    pay(p1,100)
    pay(p2,200)
    pay(p3,300) ####   这里会报错
    
    
    ## 为了方便使用,相似的功能使用一种方法名,为了统一调用,使用def pay()统一接口
    ## 强制归一化,如果父类的pay方法不重写,那么执行pay传入对象就会报错
    # 这种比较推荐
    

    第二种约束

    from abc import abstractmethod,ABCMeta
    class Pay(metaclass=ABCMeta):
        @abstractmethod
        def pay(self,money):
            ...
    
    class Qqpay(Pay):
        def pay(self,money):
            print(f'使用qq支付{money}')
    
    class Alipay(Pay):
        def pay(self,money):
            print(f'使用支付宝支付{money}')
    
    class Wechat(Pay):
        def fuqian(self,money):
            print(f"使用微信支付{money}")
    
        # def pay(self,money):
        #     print(f"使用微信支付{money}")
    
    
    def pay(obj,money):
        obj.pay(money)
    
    
    p1 = Alipay()
    p2 = Qqpay()
    p3 = Wechat()  ## 这里就会报错
    
    pay(p1,100)
    pay(p2,200)
    pay(p3,300)
    ## 使用java中抽象类的概念,个人理解,这样不太好,违背了python的包容性强的设计理念
    

    super

    super(A,self) 按照self从属于的类的mro方法返回列表中A的下一项

    命名空间

    python中所有所有名称空间,只要有层级关系(包含关系),小范围的命名空间都是有使用大范围命名空间的变量的权力,但是没有修改的权力

    并且所有取值顺序,都是先从自身找,然后范围越来越大

    忽然想到 : 相同的,内存中开辟的空间 , 我们需要借助变量名指向来使用 , 我们也只有使用的权力 , 并没有修改的权力 ; 也就是内存中开辟的空间是无法更改的 , 更改变量名的值 也只是再开一个空间 , 将变量名指向新开的空间

    内存中,开辟的空间,只要没有任何方式可以找到它,那么它就会回收

    class A:
        pass
    print(A())
    
    print(A())
    
    ## 这两个地址是一样的,因为没有任何方式能找到A()
    l = [A() for I in range(3)]
    
    # 这个列表中的三个实例化我们可以通过l 的索引找到,他就不会回收
    
    
  • 相关阅读:
    动态规划-数字三角形V1
    二分-Aggressive cows
    Unity中的UGUI之UGUI的渲染顺序--01
    关于C#中委托的学习笔记
    Unity中的协程用法以及注意事项
    Unity中的单例方法2
    Unity中关于射线的运用——第03节 射线的实际运用
    Unity中关于射线的运用——第02节 圆形射线
    Unity中关于射线的运用——第01节 线段射线
    算法之折半查找
  • 原文地址:https://www.cnblogs.com/albert0823/p/11166045.html
Copyright © 2020-2023  润新知