面向對象及命名空間

面向對象

類是類似功能的集合體java

對象

對象是類中具體的個體體現python

實例化一個對象發生了三件事

  1. 在內存中建立一個對象空間
  2. 自動執行__init__方法,而且將對象地址傳給self
  3. 執行__init__方法裏面的代碼,給對象空間封裝其屬性
self

位置參數,接收對象的地址微信

空間結構

對象查詢屬性:對象空間----類空間----父類微信支付

類查詢一個屬性: 類空間---父類ui

和局部與全局基本一致設計

依舊是,對象只有使用類屬性的權力,沒有刪除和修改的權力code

類與類之間的關係

  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 的索引找到,他就不會回收
相關文章
相關標籤/搜索