為了能夠更好的解釋類屬性和對象屬性的區別,先建立類People和兩個對象student1和student2如下:
class People(object):
# 類屬性是指定義在類的內部而且在方法的外部的屬性
money = 10000
def __init__(self,name,age,gender=1):
# 對象屬性是指定義在方法的內部的屬性,例如本例中
# name,age和gender都是對象屬性
self.name = name
self.age = age
self.gender = gender
# 建立兩個類的對象
student1 = People("張三",20)
student2 = People("李四",25)
類屬性和對象屬性的區別:
# 對象可以通過 對象名.屬性名稱 調用對象屬性和類屬性
print(student2.name)
print(student2.money)
# 而類也可以通過 類名.屬性名稱 調用類的屬性,但是
# 不能通過這種方式調用對象的屬性
# 例如類調用name屬性,會報異常
# AttributeError: type object 'People' has no attribute 'name'
print(People.money)
print(People.name)
結果如下:
類屬性和對象屬性在使用上的區別:
# 在進行運算前這三個引用的都是類屬性money
# 所以這三個的屬性money的記憶體位址都是相同的
print(id(student1.money))
print(id(student2.money))
print(id(People.money)
結果如下:
# 進行如下的運算
student1.money -= 1000
People.money -= 1000
# 再列印三者的記憶體位址
print(id(student1.money))
print(id(student2.money))
print(id(People.money))
再來看結果:
會發現student1引用的money屬性的記憶體位址已經和另外兩個的不一樣了而另外兩個的記憶體位址卻還是一樣的,原因如下:
在經過運算式student1.money -= 1000 的過程如下:第一次引用money屬性時,經曆的過程如下:會先在對象中尋找是否有money這個屬性,如果有的話,則直接進行運算如果沒有,則會去類中尋找是否有money屬性,如果在類中找到money屬性,那麼student1就會建立一個對象屬性money,在第二次調用的時候就會調用自己的對象屬性,而不是類People中的屬性了,而student2因為沒有經過運算,所以不會建立自己的money屬性,而是引用類People的屬性,所以student2和People引用的還是同一個屬性
# 當student2進行同樣的運算後,那麼student2中也會建立一個money屬性
# 此時三者的money屬性的記憶體位址都不一樣了
student2.money -= 1000
print(id(student1.money))
print(id(student2.money))
print(id(People.money))
結果如下: