一、定義和使用類
1.類的定義在面向對象的程序設計中,類是創建對象的基礎,描述了所創建對象共有的屬性和方法。它同時也有接口和結構,接口可以通過方法與類或對象進行互操作,而結構表現出一個對象中有什麼樣的屬性。這些都爲面向對象編程的3個最重要的特性(封裝性、繼承性、多態性)提供了實現手段。
類的定義就像函數定義,只是用class語句替代了def語句,同樣是在執行class的整段代碼後這個類纔會生效。進入類定義部分後,會創建出一個新的局部作用域,後面定義的類的數據屬性和函數方法都是屬於此作用域的局部變量。
2.類的使用
定義一個類,格式如下。
class 類名:
屬性列表
方法列表
在用class語句創建類時,只要把所需的屬性列表和方法列表列出即可。
>>>class Cat():
... """一次模擬貓咪的簡單嘗試"""
... name = 'tesila' # 屬性
... age = 3 # 方法
... def sleep(self):
... """模擬貓咪被命令睡覺"""
... print('%d歲的%s正在沙發上睡懶覺。'%(self.age, self.name))
... def eat(self,food):
... """模擬貓咪被命令吃東西"""
... self.food = food
... print('%d歲的%s在吃%s'%(self.age, self.name,self.food))
儘管只有一些簡單的方法,但是需要注意的地方比較多。首先根據約定,在Python中,首字母大寫的名稱指的是類(Car),這個類定義的括號中是空的,因爲是從空白來創建這個類(Python 2.0中沒有括號);如果名稱是兩個單詞,那麼兩個單詞的首字母都要大寫,例如class HotDog,這種被形象地稱爲“駝峯式命名”;函數和方法沒有區別,每個人的習慣不同而已,函數名稱一般用小寫字母或者下劃線符號連接,如“new_car”。
最後可能發現,類的函數(方法)的參數都有一個self參數,並默認爲第1個參數,這也是在編程時需要注意的地方。
二、綁定self
Python的類的方法和普通的函數有一個很明顯的區別,就是類的方法必須有個額外的參數(self),並且在調用這個方法的時候不必爲這個參數賦值。Python類方法的這個特別參數指代的是對象本身,而按照Python慣例,它用self來表示。對剛纔創建的類稍加修改,查看效果。
>>>class Cat():
... def sleep(self):
... print(self)
>>>new_cat = Cat()
>>>print(new_cat.sleep())
<__main__.Cat object at 0x00000000098656D8>
self代表當前對象的地址,能避免非限定調用時找不到訪問對象或變量。當調用sleep等函數時,會自動把該對象的地址作爲第1個參數傳入;如果不傳入地址,程序將不知道該訪問哪個對象。
self名稱也不是必需的,在Python中,self不是關鍵字,可以定義成a、b或其他名字。例如利用my_address代替self,一樣不會出現錯誤。
>>>class Test:
... def prt(my_address):
... print(my_address)
... print(my_address.__class__)
>>>t = Test()
>>>t.prt()
<__main__.Test object at 0x000000000980AF60>
<class '__main__.Test'>
簡而言之,self需要定義,但是在調用時會自動傳入;self的名字並不是規定死的,但最好還是按照約定使用self。self總是指調用時的類的實例。
三、 掌握類的專有方法
無論任何類,都有類的專有方法,它們的特殊性由代碼就能看出來,通常是用雙下劃線“__”開頭和結尾。訪問類或者對象(實例)的屬性和方法,要通過點號操作來實現,即object.attribute,當然也可以實現對屬性的修改和增加。
>>>class Example():
... pass
>>>example = Example()
>>>dir(example)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
>>>dir(Example)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
可以看到,用dir函數可以查看類的屬性和方法。由於在定義類的函數裏面只有pass語句,所以列出的結果中都以雙下劃線“__”開頭和結尾。
常用的類的專有方法
類的專有方法 | 功 能 | 類的專有方法 | 功 能 |
__init__ | 構造函數,在生成對象時調用 | __call__ | 函數調用 |
__del__ | 析構函數,釋放對象時使用 | __add__ | 加運算 |
__repr__ | 打印,轉換 | __sub__ | 減運算 |
__setitem__ | 按照索引賦值 | __mul__ | 乘運算 |
__getitem__ | 按照索引獲取值 | __div__ | 除運算 |
__len__ | 獲得長度 | __mod__ | 求餘運算 |
__cmp__ | 比較運算 | __pow__ | 乘方 |
__repr__是一個專有的方法,只有當調用repr(instance)時被調用。repr函數是一個內置函數,它用返回一個對象的字符串表示。
__cmp__在比較類實例時被調用,通常可以通過使用“==”比較任意兩個Python對象,不只是類實例。
__len__在調用len(instance)時被調用。len是Python的內置函數,可以返回一個對象的長度。字符串對象返回的是字符個數;字典對象返回的是關鍵字的個數;列表或序列返回的是元素的個數。對於類和對象,定義__len__方法,可以自己定義長度的計算方式,然後調用len(instance),Python則會將調用定義的__len__專用方法。
__del__在調用del instance[key]時調用,它會從字典中刪除單個元素。
__call__方法讓一個類表現得像一個函數,可以直接調用一個類實例。
__setitem__方法可以讓任何類像字典一樣保存鍵-值對。
__getitem__方法可以讓任何類表現得像一個序列。
任何定義了__cmp__方法的類都可以用==進行比較。在類的應用中,最常見的是將類實例化,再通過實例來執行類的專有方法。
四、練習
創建一個Car類,爲其賦予車輪數(4)、顏色(red)的屬性,並定義函數來輸出“汽車有4個車輪,顏色是紅色。”及“車行駛在學習的大道上。”,再調用類的方法(函數)。
參考代碼:
class Car(): # 創建類
"""一次模擬汽車的簡單嘗試"""
wheelNum = 4 # 增加屬性
color = 'red'
def getCarInfo(self,name): # 定義getCarInfo函數
self.name = name
print(self.name,'有%d個車輪, 顏色是%s。'%(self.wheelNum,self.color))
def run(self): # 定義run函數
print('車行駛在學習的大道上。')
new_car = Car() # 調用Car類
print(new_car.getCarInfo('Land Rover')) # 調用getCarInfo函數
print(new_car.run()) # 調用run函數
Python面向對象編程系列文章兩週一更!
文章未經博主同意,禁止轉載!