公共屬性
在 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 屬性、方法
總的來說,和公共變數沒有什麼特別大的區別
總結
無論是受保護型變數還是私有變數,其實在外部還是能訪問的,所以並不能真正控制屬性的訪問許可權