Python 速查手冊

6.13 物件模型

所有 Python 的物件 (object) 是按照一套預先規劃好的模型來設置的,也就是說,我們在設計類別的時候,需要按照 Python 預設的模式來進行,例如前後被兩條底線包圍的方法 (method) ,像是 __init__()__str__() ,或是 __doc__ 屬性 (attribute) 等等。

最基本的物件是 objectobject 是內建型態 (built-in type) 的名稱,也是內建函數 (built-in function) ,利用內建函數 object() 會回傳 object 型態的實體 (instance) 物件,這邊用另一個內建函數 dir() 取得 object 型態所定義的所有屬性及方法名稱,可以看到這些名稱都被前後兩條底線包圍

print(dir(object))

#《程式語言教學誌》的範例程式
# https://kaiching.org/
# 檔名:data01.py
# 功能:示範定義類別
# 作者:張凱慶

於命令列執行以上程式,結果如下

$ python3 data01.py
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
$

繼續看到 None 包含的所有屬性及方法,同樣全部被前後兩條底線包圍,此外注意到 __bool__ ,由於 None 可表示真假值,所以會有這個方法

print(dir(None))

#《程式語言教學誌》的範例程式
# https://kaiching.org/
# 檔名:data02.py
# 功能:示範定義類別
# 作者:張凱慶

於命令列執行以上程式,結果如下

$ python3 data02.py
['__bool__', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
$

繼續看到整數 22 包含的所有屬性及方法,整數型態的物件就有更多屬性及方法了,除了前後被兩條底線包圍的名稱外,還有些專屬於整數型態的屬性及方法

print(dir(22))

#《程式語言教學誌》的範例程式
# https://kaiching.org/
# 檔名:data03.py
# 功能:示範定義類別
# 作者:張凱慶

於命令列執行以上程式,結果如下

$ python3 data03.py
['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getnewargs__', '__gt__', '__hash__', '__index__', '__init__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']
$

再來看到串列 (list) 包含的所有屬性及方法,同樣有很多專屬於串列的屬性及方法,還有需要注意串列跟整數的物件模型是不同的,例如串列有 __iter__() 方法,整數卻沒有這個方法, __iter__() 方法是讓串列當作可迭代的物件之用

print(dir([]))

#《程式語言教學誌》的範例程式
# https://kaiching.org/
# 檔名:data04.py
# 功能:示範定義類別
# 作者:張凱慶

於命令列執行以上程式,結果如下

$ python3 data04.py
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
$

再來看看自行定義的 Demo 類別 (class) ,可以看到自行定義的類別,預設的屬性及方法比 object 還多,像是 __dict__ 屬性,這讓自行定義的類別可以擴充自行設定的屬性, object 型態卻不行

class Demo:
    pass
    
print(dir(Demo))

#《程式語言教學誌》的範例程式
# https://kaiching.org/
# 檔名:data05.py
# 功能:示範定義類別
# 作者:張凱慶

於命令列執行以上程式,結果如下

$ python3 data05.py
['__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__']
$

基本上自行定義的類別需要一定程度的客製化,最基本的就是需要定義 __init__()__del__()__str__() 等三個方法

__init__()
__del__()
__str__()

更進一步就是比較物件實體之間的關係,那就是重新定義這六個方法,像是 __lt__() 判斷小於關係, __eq__() 判斷是否相等

__lt__(), <
__le__(), <=
__eq__(), ==
__ne__(), !=
__gt__(), >
__ge__(), >=

其他還有很多可以自訂的客製化方法,像是跟屬性存取相關的就有這五個方法,更多資訊請詳閱官方的語言手冊文件

__getattr__()
__getattribute__()
__setattr__()
__delattr__()
__dir__()

上一頁: 6.12 迭代器
Python 速查手冊 - 目錄
下一頁: 單元 7 - 模組與 __name__
回 Python 教材首頁