公共屬性
在 Python 的類裡面,所有屬性和方法預設都是公共的
class PoloBlog: # 公共屬性 sum = 0 # 構造方法 def __init__(self, name): self.name = name # 公共方法 def test(self): ...
但Python也可以設定受保護、私有型別的變數or方法
私有型別的屬性、方法
- 在實際開發中,物件的某些屬性或方法可能只希望在物件的內部被使用,而不希望在外部被訪問到
- 私有屬性:就是物件不希望公開訪問的屬性
- 私有方法:就是物件不希望公開訪問的方法
定義方式,類圖
在屬性、方法名前加兩個下劃線就是私有屬性、私有方法了
程式碼
# 私有屬性、方法 class Person: # 構造方法 def __init__(self, name, age): self.name = name self.__age = age # 例項方法 def pinrtMsg(self): print("name:", self.name, " age:", self.__age) # 私有方法 def __getAge(self): print("age is ", self.__age) person = Person("小菠蘿", 24) # 直接呼叫私有屬性、私有方法 - 會報錯 print(person.__age) print(person.__getAge) # 輸出結果 print(person.__age) AttributeError: 'Person' object has no attribute '__age' print(person.__getAge) AttributeError: 'Person' object has no attribute '__getAge'
看看 Pycharm 的程式碼聯想
壓根不會聯想,因為是私有屬性、私有方法,不允許在物件外部被使用
通過公共方法訪問私有屬性
person = Person("小菠蘿", 24) person.printMsg() # 輸出結果 name: 小菠蘿 age: 24
類屬性私有化
# 類屬性的私有化 class Person: __sum = 0 @classmethod def getSum(cls, num): # 呼叫私有類方法 cls.__sumAdd(num) print(cls.__sum) @classmethod def __sumAdd(cls, num): cls.__
重點
- 子類無法訪問父類的私有變數、方法
- 私有變數只有本類的內部能直接呼叫
- But!外部真的不能訪問嗎?
偽私有屬性和私有方法
- 其實 Python 中,並沒有真正意義上的私有,仍然可以在外部訪問私有屬性、私有方法
- 因為,在給私有屬性、方法命名時,實際是對名稱做了一些特殊處理,使得外界無法訪問到
- 處理方式:在名稱前面加上 _類名 ,私有屬性、方法就會變成 _類名__名稱
# 間接呼叫 class Person: __sum = 0 # 構造方法 def __init__(self, name): self.__name = name # 私有方法 def __getName(self): print("name is ", self.__name) # 呼叫類私有屬性 print(Person._Person__sum) person = Person("小菠蘿") # 呼叫私有屬性 print(person._Person__name) # 呼叫私有方法 person._Person__getName() # 輸出結果 0 小菠蘿 name is 小菠蘿
無論是類物件還是例項物件,都可以通過 ._類名__名稱 來呼叫私有屬性、方法,這算是一種間接呼叫
受保護型別的屬性、方法
- 受保護型別一般會稱為:protect 屬性,學過 Java 的應該都瞭解
- 在屬性和方法前加一個下劃線就是 protect 型別了,私有型別是兩個下劃線
# 受保護型別 class PoloBlog: _sum = 0.0 # 構造方法 def __init__(self, name): self._name = name # 保護方法 def _printName(self): print(self._name) # 類方法 @classmethod def _classMethod(cls): print(cls._sum) blog = PoloBlog("小菠蘿") # 列印保護型別的類屬性 print(PoloBlog._sum) # 列印保護型別的例項屬性 print(blog._name) # 例項物件呼叫保護型別的例項方法 blog._printName() # 例項物件呼叫保護型別的類方法 blog._classMethod() # 類物件呼叫保護型別的類方法 PoloBlog._classMethod() # 輸出結果 0.0 小菠蘿 小菠蘿 0.0 0.0
知識點
- 父類的 protect 屬性,子類可以繼承
- 例項物件、類物件都能直接呼叫 protect 屬性、方法
總的來說,和公共變數沒有什麼特別大的區別
總結
無論是受保護型變數還是私有變數,其實在外部還是能訪問的,所以並不能真正控制屬性的訪問許可權