我們知道,無論是在類別中定義的屬性還是方法,在類別的外部,都無法直接呼叫它們,因此,我們完全可以把類別看做是一個獨立的作用域(稱為類別命名空間) ,則類別屬性其實就是定義在類別命名空間內的變數(類別方法其實就是定義的類別命名空間中的函數)。
根據定義屬性的位置不同,類別屬性又可細分為類別屬性(後續以類別變數表示)和實例屬性(後續以實例變數表示)。
類別變數(類別屬性) (建議學習:Python影片教學)
類別變數指的是定義在類別中,但在各個類別方法外的變數。類別變數的特徵是:所有類別的實例化物件都可以共享類別變數的值,也就是類別變數可以在所有實例化物件中作為公用資源。
注意,類別變數建議直接用類別名稱訪問,但也可以使用物件名稱存取。
例如,下面程式碼定義了一個Address 類,並為該類別定義了多個類別屬性:
class Address : detail = '广州' post_code = '510660' def info (self): # 尝试直接访问类变量 #print(detail) # 报错 # 通过类来访问类变量 print(Address.detail) # 输出 广州 print(Address.post_code) # 输出 510660 #创建 2 个类对象 addr1 = Address() addr1.info() addr2 = Address() addr2.info() # 修改Address类的类变量 Address.detail = '佛山' Address.post_code = '460110' addr1.info() addr2.info()
該程式中,第二、三行程式碼為Address 定義了兩個類別變數。當程式中第一次呼叫 Address 物件的 info() 方法輸出兩個類別變數時,將會輸出這兩個類別變數的初始值。接下來程式透過 Address 類別修改了兩個類別變數的值,因此當程式第二次透過 info() 方法輸出兩個類別變數時,將會輸出這兩個類別變數修改之後的值。
運行上面程式碼,將會看到如下輸出結果:
广州 510660 广州 510660 佛山 460110 佛山 460110
透過輸出結果可以看到,addr1 和addr2 共享類別變量,換句話說,改變類別變數的值會作用於該類別所有的實例化物件。
實例變數指的是定義在類別的方法中的屬性,它的特點是:只作用於呼叫方法的物件。
注意,實例變數只能透過物件名稱訪問,無法透過類別名稱直接存取。
Python 允許透過物件存取類別變量,但無法透過物件修改類別變數的值。因為,透過物件修改類別變數的值,不是在給“類別變數賦值”,而是定義新的實例變數。
例如如下程式:
class Inventory: # 定义两个类变量 item = '鼠标' quantity = 2000 # 定义实例方法 def change(self, item, quantity): # 下面赋值语句不是对类变量赋值,而是定义新的实例变量 self.item = item self.quantity = quantity # 创建Inventory对象 iv = Inventory() iv.change('显示器', 500) # 访问iv的item和quantity实例变量 print(iv.item) # 显示器 print(iv.quantity) # 500 # 访问Inventory的item和quantity类变量 print(Inventory.item) # 鼠标 print(Inventory.quantity) # 2000
上面程式中,第8、9 行程式碼透過實例對item、quantity 變數賦值,看起來很像是對類別變數賦值,但並不是,它們的作用是:重新定義了兩個實例變數。
類別中,實例變數和類別變數可以同名,但是在這種情況下,使用類別物件將無法呼叫類別變數,因為它會首選實例變量,因此這也是不推薦「類別變數使用對象名調用」的原因。
上面程式在呼叫Inventory 物件的change() 方法之後,存取Inventory 物件的item、quantity 變量,由於物件本身己有這兩個實例變量,因此程式會輸出該物件的實例變量的值;接下來程式透過Inventory 存取它的item、quantity 兩個類別變量,此時才是真的存取類別變數。
執行上面程序,將看到如下輸出結果:
显示器 500 鼠标 2000
以上是python類別變數和實例變數的詳細內容。更多資訊請關注PHP中文網其他相關文章!