類的公有屬性
一、概念
我們前面提到類的私有屬性,也就是類中不能直接訪問的。但是不是可以直接訪問的屬性就是公有屬性呢?其實也不是。在__init__()構造函數中的屬性,對外基本都可以訪問,但是他們並不是公有屬性。那什麽叫公有屬性呢?
定義: 指的是所屬這個類的所有對象,都可以訪問的屬性,叫做公有屬性。
二、屬性
2.1 成員屬性
class Person(object): def __init__(self, name, job, phone, address): self.name = name # 成員屬性,屬於某個實例對象 self.job = job self.phone = phone self.__address = address def get_private(self): return self.__address def sayhi(self): print("hell,%s" % self.name) p1 = Person(‘Bigberg‘, ‘Doctor‘, ‘8833421‘, ‘hz‘) p2 = Person(‘Ashlex‘, ‘Police‘, ‘8833232‘, ‘bj‘)
print(p1.job, p2.job)
# 輸出
Doctor Police
我們在Person類下定義了兩個對象,p1和p2。很顯然我們沒有辦法讓p1來訪問到p2 的job屬性,即Police。那麽在構造函數__init__()中的self.name等屬性,被稱之為 成員屬性。
2.2 公有屬性
class Person(object): nationality = ‘CN‘ # 定義公有屬性 def __init__(self, name, job, phone, address): self.name = name self.job = job self.phone = phone self.address = address def sayhi(self): print("hell,%s" % self.name) p1 = Person(‘Bigberg‘, ‘Doctor‘, ‘8833421‘, ‘hz‘) p2 = Person(‘Ashlex‘, ‘Police‘, ‘8833232‘, ‘bj‘) print(p1.nationality) print(p2.nationality) # 輸出 CN CN
公有屬性而言,所有實例對象訪問它得到的值是一樣的。
三、公有屬性的特性
我們不僅可以訪問,還能改變公有屬性。
class Person(object): nationality = ‘CN‘ # 定義公有屬性 def __init__(self, name, job, phone, address): self.name = name self.job = job self.phone = phone self.address = address def sayhi(self): print("hell,%s" % self.name) p1 = Person(‘Bigberg‘, ‘Doctor‘, ‘8833421‘, ‘hz‘) p2 = Person(‘Ashlex‘, ‘Police‘, ‘8833232‘, ‘bj‘) print(Person.nationality) # 調用 公有屬性 Person.nationality = ‘us‘ # 改變 公有屬性 print(Person.nationality) #輸出 CN us
3.1 單個實例調用和改變公有屬性
# 依據上例 print("--------Befoer change---------") print(Person.nationality) print(p1.nationality) print(p2.nationality) print("--------after change---------") print(Person.nationality) p1.nationality = ‘JP‘ print(p1.nationality) print(p2.nationality) # 輸出
--------Befoer change---------
CN
CN
CN
--------after change---------
US
JP
US
p1在修改之前我們可以很好理解,因為大家都是調用的類Person的公有屬性nationality,所以p1、p2的國籍屬性是一樣的,都是 ‘CN‘。但是為什麽在p1修改過公有屬性後,p2的國籍屬性沒有改變呢?
在我們定義一個Person類的時候,其實在內存中就已經存在了,當然也包含了這個類的公有屬性。在最初實例p1去調用類Person的nationality這個屬性時,是直接引用類當中nationality的內存地址,而不是自己新增一個屬性叫nationality。
如下所示:
print(id(Person.nationality)) print(id(p1.nationality)) print(id(p2.nationality)) print(Person.nationality, p1.nationality, p2.nationality) #輸出 1751236836128 1751236836128 1751236836128 CN CN CN
這就可以解釋為什麽在Person類中的nationality改變為 ‘US‘ 時,p2也跟著改變。因為是直接引用內存當中的值。
p1.nationality = ‘JP‘
在p1直接賦值nationality這個屬性後,其實就實例p1為自己新增了一個成員變量,叫做nationality。只是他們的名稱相同而已,但是兩者之間並沒有聯系,甚至內存地址也不相同。
# p1.nationality = ‘JP‘ print(id(Person.nationality)) print(id(p1.nationality)) print(id(p2.nationality)) print(Person.nationality, p1.nationality, p2.nationality) #輸出 2434579585096 2434579585152 2434579585096 US JP US
所以 p1.nationality=‘JP‘,並沒有修改類Person的公有屬性,而是為自己創建了一個新的成員屬性,因此p1的改變對類的公有屬性沒有影響。
類的公有屬性