Python類的基礎--設計、使用

馬哥教育發表於2020-10-24

類是事物功能和屬性的抽象,物件是類的例項化。就像人人都知道小汽車可以幹什麼什麼的,但光想小汽車如何好是沒有用的,得開車或坐才能感受到小汽車的好。人腦裡的小汽車是抽象的,即類,而坐上的某輛車是小汽車的例項化,即物件。所以,如果一門語言提供了、支援物件導向程式設計的機制,那麼首先得先設計程式所需要的類,然後再在程式裡將這些類例項化產生物件,通過物件這個程式元素(和變數、函式等起著相同的作用,構成程式的基本元素),所以類的設計是物件導向程式設計是否有效、合理、成功的關鍵。

類總的來說是專有資料用專用方法處理,即資料和處理資料方法的集合,故類的裡有資料(屬性)和函式(功能),且類裡的資料必須用類裡的方法來操作處理。

類裡的這些函式也有時又稱方法、成員函式,如果方法或函式作用於類本身稱之為類方法,如果方法作用於由類產生出的例項物件上,這些方法稱之為例項物件的方法。類裡的資料稱為屬性(類屬性和例項物件屬性)、成員變數。

類不能無源而生,需有自己的父類,而object這個類是Python下的根類(base class),也就是說使用者自己的類可以繼承object 這個類作為自己(父)類的起點,類的父類需要用圓括號括起來放在類名字的後邊。

定義類

基於上邊講述,定義一個常規的類格式如下:

class 類名字(父類序列):
    類的成員變數 = 初值
    def __init__(self, 形參序列):
        self.例項物件的成員變數名 = 初值
        其他語句

    def 其他例項物件函式名(self,形參序列):
        語句

    @classmethond
    def 類的成員函式名(cls,形參序列):
        cls.類的成員變數名 = 初值
        語句

    @staticmethond
    def 函式名(形參序列):
        語句

類的語法格式裡出現了一些奇奇怪怪的符號,下面一一解釋一下。 class和定義函式的def一樣是Python裡的關鍵字,用於定義一個類的識別符號。

位於class下和_ _init_ _函式間宣告的變數是類的變數,可被類或類的物件共有。

__init__可以成為類的例項物件的建構函式,每次通過類建立一個該類的物件是呼叫此函式,所以其下的以sefl.字首的變數是每個建立好了的例項(化)物件的所獨有的。換句話說,有多少個類的物件記憶體裡就有多少份這個例項物件變數存在。就像生產了多少小汽車就有多少個方向盤似的。

self代表執行時的類的例項物件本身,一般在類的內部設計時出現,在程式裡使用物件程式設計時不用self。在例項物件的成員函式裡以self.字首的變數是例項物件的成員變數,沒有self.的變數是本方法函式的區域性變數。

cls和self出現在構造和例項物件函式的第一個引數位置上一樣,cls關鍵字出現在類的方法函式裡,區分於物件函式和變數時會用到。在類的函式裡以cls.字首的變數也是類的成員變數,沒有這個字首的是區域性變數。

@classmethon這個關鍵字是修飾器,修飾也是說下面的函式是類的方法函式而不是類的物件的方法函式。

@staticmethod這個也是修飾器,說明接下來的函式是一個靜態函式,和例項物件的成員函式、類函式的區別主要在第一個形參,既無self又無cls。可以被類或物件直接呼叫。差不多解釋完了,下面來看一個具體的類的例項程式。

定義一個類的示例

下面建立一個Horse類,類裡除了有例項物件的方法函式、類方法函式和靜態方法函式,還有例項物件成員變數和類變數。

# coding:utf-8
class Horse(object):
    variety = "大宛馬"
    def __init__(self, name = "green", height = 0.5, length = 1.3, sex = "male"):   
        self.name = name
        self.height = height
        self.length = length
        self.sex = sex
        print "A baby horse is born called", self.name
    @classmethod
    def pp(cls):
        print cls.variety, Horse.variety, cls.address
    @classmethod
    def print_variety(cls):
        cls.address = "xi'an"
        print cls.variety, Horse.variety, cls.address
        Horse.pp()

    def print_info(self):
        print self.name, self.height, self.length, self.sex, Horse.variety#,Horse.address
        Horse.print_variety()

    @staticmethod
    def print_ci(x, y):
        print x, y

1).出現在class下一行的variety是類Horse的變數,是類變數,可以通過Horse.variety在類的內部或者外部任何地方被訪問。

2).__init__函式是Horse類的例項物件的建構函式,每次建立一個Horse類的例項物件時,這個函式均會被呼叫執行,其下以self.開始的變數是每個例項物件的成員變數,即標的這個例項物件的屬性、特徵用的。

3). 用修飾器@classmethod修飾的兩個函式pp、print_variety,是類Horse的類函式,類函式只可通過類或cls使用。在pp這個函式裡可以看出一點,在類的內部類變數的使用需字首類名.或cls.。

類名.類變數
cls.類變數

從print_variety函式可以看出,在類的內部可以通過類呼叫類的方法函式。

類名.類方法

4).用@staticmethod修飾的print_ci函式是靜態函式,它的第一個引數不是特殊的self或者cls,靜態函式可在類內部或類的外部呼叫,也可被類的物件呼叫。

建立物件

物件導向程式設計實際是在設計好類以後,用與類同名的函式來建立類的物件,用類的物件呼叫物件的方法函式來編寫整個程式,有時可能根據需要少量地用類呼叫類方法的語句程式碼出現,一般都是物件呼叫類裡設計好的物件方法函式來完成整個程式的功能,故稱物件導向程式設計。

建立類的例項物件的語法:

變數 = 類名([引數序列])

通過這樣的方式建立類的例項物件本質是呼叫了類裡的_ _ init_ ()方法函式,括號裡的[引數序列]意思是看 _ init_ _()方法函式是否有除self外的其他形參,如無,換括號裡沒有任何實參。

需要特別說明的是任何例項物件的self形參不用賦值,在Python解譯執行程式語句時self代表點兒運算子(.)前的例項物件,或者說self被Python賦值為點兒運算子前的例項物件。

a = Horse(sex = "male")
b = Horse(name = "marong", sex = "female")

物件導向程式設計示例

物件導向程式設計,需要兩步,第一步先設計好類,第二步基於類建立物件並通過物件呼叫函式來完成整個程式需要實現的功能。下面是本節課設計的一個Horse類的物件導向程式設計的完整示例。

# coding:utf-8
class Horse(object):
    variety = "大宛馬"
    def __init__(self, name = "green", height = 0.5, length = 1.3, sex = "male"):       
        # self.name是成員變數,name是形參、區域性變數
        self.name = name
        self.height = height
        self.length = length
        self.sex = sex
        print "A baby horse is born called", self.name

    def print_info(self):
        print self.name, self.height, self.length, self.sex, Horse.variety#,Horse.address
        Horse.print_variety() # 在物件方法裡通過類呼叫類方法,避免
        Horse().print_ci(200, 100)# 物件呼叫靜態方法
        Horse.print_ci(200, 100) # 類呼叫靜態方法

    @staticmethod
    def print_ci(x, y):
        print x, y

    @classmethod
    def pp(cls):
        # 類使用類變數
        print cls.variety, Horse.variety, cls.address
        #cls.print_variety()
        print Horse().name  # 物件使用物件的成員變數
    @classmethod
    def print_variety(cls):
        cls.address = "xi'an"
        print "type", type(cls.address)
        print cls.variety, Horse.variety, cls.address
        Horse.pp()# 類呼叫類方法
        Horse().print_ci(100, 100)# 物件呼叫靜態方法

a = Horse("xiaoxuanfeng")
b = Horse("pilihuo", sex = "female")
a.print_info()
b.print_info()
Horse.print_variety()
print "*" * 20
Horse.pp() # 類呼叫類方法
Horse.print_ci(12, 23)# 類外類呼叫靜態方法
a.print_ci(23, 31) # 類外物件呼叫靜態方法

相關文章