類別屬性 (class attribute) 是專屬於類別物件的屬性 (attribute) ,實體屬性 (instance attribute) 則是專屬於實體 (instance) 物件 (object) 的屬性,一般來說,類別屬性用類別方法 (class method) 設定及存取,實體屬性則是利用實體物件的方法 (method) 來設定及存取。
這裡先來看到如何在類別中定義類別屬性及實體屬性,類別屬性的定義直接放在關鍵字 (keyword) class 之下,跟方法定義的關鍵字 def 具有相同的縮排層級,實體屬性則是放在方法定義中,必須用方法的參數 (parameter) self 來設定,這個例子的類別屬性跟實體屬性的識別字 (identifier) 都是英文小寫字母 i ,方法中如果要存取或設定類別屬性,必須連帶使用類別名稱,此例的類別屬性 i 記錄實體物件被建立的次數
class Demo:
i = 0 #類別屬性
def __init__(self, i):
self.i = i #實體屬性
Demo.i += 1
d1 = Demo(9527)
print(d1.i)
print(Demo.i)
d2 = Demo(9528)
print(d2.i)
print(Demo.i)
#《程式語言教學誌》的範例程式
# http://kaiching.org/
# 檔名:att01.py
# 功能:示範定義類別
# 作者:張凱慶
於命令列執行以上程式,結果如下
$ python3 att01.py |
9527 |
1 |
9528 |
2 |
$ |
如果類別屬性跟實體屬性的識別字名稱是不同的,實體物件就可以直接存取類別屬性,例如 Demo2 把實體屬性改為英文小寫字母 j ,這樣就能在實體變數直接用 i 取得類別屬性值
class Demo2:
i = 0 #類別屬性
def __init__(self, j):
self.j = j #實體屬性
Demo2.i += 1
d1 = Demo2(9529)
print(d1.j)
print(d1.i)
print(Demo2.i)
d2 = Demo2(9530)
print(d2.j)
print(d2.i)
print(Demo2.i)
#《程式語言教學誌》的範例程式
# http://kaiching.org/
# 檔名:att02.py
# 功能:示範定義類別
# 作者:張凱慶
於命令列執行以上程式,結果如下
$ python3 att02.py |
9529 |
1 |
1 |
9530 |
2 |
2 |
$ |
在類別方法中預設的參數 cls 可以取得類別屬性,如此例類別方法 addi() 將類別屬性 i 遞增
class Demo3:
i = 0 #類別屬性
def __init__(self, i):
self.i = i #實體屬性
Demo3.addi()
@classmethod
def addi(cls):
cls.i += 1
d = Demo3(9531)
print(d.i)
print(Demo3.i)
Demo3.addi()
print(Demo3.i)
#《程式語言教學誌》的範例程式
# http://kaiching.org/
# 檔名:att03.py
# 功能:示範定義類別
# 作者:張凱慶
於命令列執行以上程式,結果如下
$ python3 att03.py |
9531 |
1 |
2 |
$ |
基本上類別屬性無法存取或修改實體屬性值,因為實體物件就已經是從類別創建出的個別實體,實體物件跟類別物件只有在類別屬性及類別方法上有連結,然而類別方法可以回傳同類別的實體物件,如此例 Demo4 的類別方法 addi() 回傳全新的 Demo4 型態的實體物件,並且以 addi() 的參數當作 Demo4 建構子 (constructor) 的參數
class Demo4:
i = 0 #類別屬性
def __init__(self, j):
self.j = j #實體屬性
Demo4.i += 1
@classmethod
def addi(cls, p):
cls.i += 1
return Demo4(p)
d1 = Demo4(9532)
print(d1.i)
print(d1.j)
d2 = Demo4.addi(9533)
print(Demo4.i)
#《程式語言教學誌》的範例程式
# http://kaiching.org/
# 檔名:att04.py
# 功能:示範定義類別
# 作者:張凱慶
於命令列執行以上程式,結果如下
$ python3 att04.py |
1 |
9532 |
3 |
$ |
相關教學影片