標籤:ram 特殊變數 決定 返回 list 字元 函數 列印 pre
物件導向最重要的概念就是類(Class)和執行個體(Instance),必須牢記類是抽象的模板,比如Student類,而執行個體是根據類建立出來的一個個具體的“對象”,每個對象都擁有相同的方法,但各自的資料可能不同。
仍以Student類為例,在Python中,定義類是通過class關鍵字
定義好了Student類,就可以根據Student類建立出Student的執行個體,建立執行個體是通過類名+()實現的
由於類可以起到模板的作用,因此,可以在建立執行個體的時候,把一些我們認為必須綁定的屬性強制填寫進去。通過定義一個特殊的__init__方法
如果要讓內部屬性不被外部存取,可以把屬性的名稱前加上兩個底線__,在Python中,執行個體的變數名如果以__開頭,就變成了一個私人變數(private),只有內部可以訪問,外部不能訪問
需要注意的是,在Python中,變數名類似__xxx__的,也就是以雙底線開頭,並且以雙底線結尾的,是特殊變數,特殊變數是可以直接存取的,不是private變數,所以,不能用__name__、__score__這樣的變數名。
有些時候,你會看到以一個底線開頭的執行個體變數名,比如_name,這樣的執行個體變數外部是可以訪問的,但是,按照約定俗成的規定,當你看到這樣的變數時,意思就是,“雖然我可以被訪問,但是,請把我視為私人變數,不要隨意訪問”。
雙底線開頭的執行個體變數是不是一定不能從外部存取呢?其實也不是。不能直接存取__name是因為Python解譯器對外把__name變數改成了_Student__name,所以,仍然可以通過_Student__name來訪問__name變數
在OOP程式設計中,當我們定義一個class的時候,可以從某個現有的class繼承,新的class稱為子類(Subclass),而被繼承的class稱為基類、父類或超類(Base class、Super class)。
比如,我們已經編寫了一個名為Animal的class,有一個run()方法可以直接列印
當我們需要編寫Dog和Cat類時,就可以直接從Animal類繼承:
class Dog(Animal): passclass Cat(Animal): pass
當子類和父類都存在相同的run()方法時,我們說,子類的run()覆蓋了父類的run(),在代碼啟動並執行時候,總是會調用子類的run()。這樣,我們就獲得了繼承的另一個好處:多態
對於一個變數,我們只需要知道它是Animal類型,無需確切地知道它的子類型,就可以放心地調用run()方法,而具體調用的run()方法是作用在Animal、Dog、Cat還是Tortoise對象上,由運行時該對象的確切類型決定,這就是多態真正的威力:調用方只管調用,不管細節,而當我們新增一種Animal的子類時,只要確保run()方法編寫正確,不用管原來的代碼是如何調用的。這就是著名的“開閉”原則
使用type()
首先,我們來判斷物件類型,使用type()函數:
基本類型都可以用type()判斷對於class的繼承關係來說,使用type()就很不方便。我們要判斷class的類型,可以使用isinstance()函數
總是優先使用isinstance()判斷類型
如果要獲得一個對象的所有屬性和方法,可以使用dir()函數,它返回一個包含字串的list,比如,獲得一個str對象的所有屬性和方法
從上面的例子可以看出,在編寫程式的時候,千萬不要對執行個體屬性和類屬性使用相同的名字,因為相同名稱的執行個體屬性將屏蔽掉類屬性,但是當你刪除執行個體屬性後,再使用相同的名稱,訪問到的將是類屬性。
我整理的Python規則(2)