1. 程式人生 > >Python的類(二)

Python的類(二)

bject class -1 div 所在 公開 nts 被調用 默認

一、類的重寫

  對於父類的方法,只要它不符合子類模擬的實物的行為,都可對其進行重寫。為此,可在子類中定義一個這樣的方法,即它與要重寫的父類方法同名。這樣, Python將不會考慮這個父類方法,而只關註你在子類中定義的相應方法。 實例如下:

class parent():
    name = parent
    sex = F

    def __init__(self):
        print (my name is {0}.format(self.name))

    def get_name(self):
        return self.name

    
def get_sex(self): return self.sex class child(parent): name = child sex = M def __init__(self): print (my name is {0}.format(self.name)) def hello(self): print (hello world!) def get_name(self): print ("something ") a = child() a.hello() a.get_name()
print (a.get_sex())

  結果:

技術分享

  super 是用來解決多重繼承問題的,直接用類名調用父類方法在使用單繼承的時候沒問題,但是如果使用多繼承,會涉及到查找順序(MRO)、重復調用(鉆石繼承)等種種問題。總之前人留下的經驗就是:保持一致性。要不全部用類名調用父類,要不就全部用 super,不要一半一半。實例如下:

class parent(object):
    parent_name = parent
    sex = F

    def __init__(self,address,age):
        self.address = address
        self.age 
=age print (my name is {0}.format(self.parent_name)) def get_name(self): print (parent parent parent parent) return self.parent_name def get_sex(self): return self.sex class child(parent): child_name = child # sex = ‘M‘ def __init__(self,address,age): super(child,self).__init__(address,age) print (my name is {0}.format(self.child_name)) def hello(self): print (hello world!) def get_name(self): super(child,self).get_name() print ("something ") a = child(beijing,12) a.hello() a.get_name() print (a.get_sex()) print (a.address) print (a.age)

  結果:

技術分享

  在super機制裏可以保證公共父類僅被執行一次,至於執行的順序,是按照mro進行的(E.__mro__)。
  註意:

  • super繼承只能用於新式類,用於經典類時就會報錯。
  • 新式類:必須有繼承的類,如果沒什麽想繼承的,那就繼承object
  • 經典類:沒有父類,如果此時調用super就會出現錯誤:『super() argument 1 must be type, not classobj』

  super小結:

  1. super並不是一個函數,是一個類名,形如super(B, self)事實上調用了super類的初始化函數,
產生了一個super對象;
  2. super類的初始化函數並沒有做什麽特殊的操作,只是簡單記錄了類類型和具體實例;
  3. super(B, self).func的調用並不是用於調用當前類的父類的func函數;
  4. Python的多繼承類是通過mro的方式來保證各個父類的函數被逐一調用,而且保證每個父類函數
只調用一次(如果每個類都使用super);
  5. 混用super類和非綁定的函數是一個危險行為,這可能導致應該調用的父類函數沒有調用或者一
個父類函數被調用多次。

二、類的私有變量

  在Python中可以通過在屬性變量名前加上雙下劃線定義屬性為私有屬性

  特殊變量命名:

   1、 _xx 以單下劃線開頭的表示的是protected類型的變量。即保護類型只能允許其本身與子類進行訪問。若內部變量標示,如: 當使用“from M import”時,不會將以一個下劃線開頭的對象引入 。

   2、 __xx 雙下劃線的表示的是私有類型的變量。只能允許這個類本身進行訪問了,連子類也不可以用於命名一個類屬性(類變量),調用時名字被改變(在類FooBar內部,__boo變成_FooBar__boo,如self._FooBar__boo)

  3、 __xx__定義的是特列方法。用戶控制的命名空間內的變量或是屬性,如init , __import__或是file 。只有當文檔有說明時使用,不要自己定義這類變量。 (就是說這些是python內部定義的變量名)

  在這裏強調說一下私有變量,python默認的成員函數和成員變量都是公開的,沒有像其他類似語言的public,private等關鍵字修飾.但是可以在變量前面加上兩個下劃線"_",這樣的話函數或變量就變成私有的.這是python的私有變量軋壓(這個翻譯好拗口),英文是(private name mangling.) **情況就是當變量被標記為私有後,在變量的前端插入類名,再類名前添加一個下劃線"_",即形成了_ClassName__變量名.**

  實例如下:

class A(object):
    _name = ling
    __sex = F
    def hello(self):
        print (self._name)
        print (self.__sex)

    def get_sex(self):
        return self.__sex

a = A()
print (a._name)
a.hello()
print (a.get_sex())

結果:

技術分享

  Python內置類屬性

  __dict__ : 類的屬性(包含一個字典,由類的數據屬性組成)

  __doc__ :類的文檔字符串

  __module__: 類定義所在的模塊(類的全名是‘__main__.className‘,如果類位於一個導入模塊mymod中,那麽className.__module__ 等於 mymod)

  __bases__ : 類的所有父類構成元素(包含了一個由所有父類組成的元組)

Python的類(二)