封裝之如何隱藏對象及封裝的意義
阿新 • • 發佈:2018-09-19
屬性和方法 err draw 輸出 數據屬性 init sin sta ret
python中通常在屬性和方法前加__(兩條下劃線)來進行屬性和方法的隱藏。
特點:
1.在類外無法直接obj.__AttrName
2.在類內部可以直接使用obj.__AttrName
3.子類無法覆蓋父類__開頭的屬性
1.在類外無法直接obj.__AttrName
class A: def __init__(self, name, life): self.__name = name self.__life = life def __run(self): print(‘run‘) def sing(self): self.__run() print(‘sing‘) b = A(‘gaohui‘, 100) print(b.__name) 報錯: AttributeError: ‘A‘ object has no attribute ‘__name‘
2.在類內部可以直接使用obj.__AttrName
class A: def __init__(self, name, life): self.__name = name self.__life = life def __run(self): print(‘run‘)def sing(self): self.__run() print(‘sing‘) b = A(‘gaohui‘, 100) b.sing() 輸出結果: run sing
此時的__run正常輸出了,因為在類的定義時,self.__run()已經便成了self._A__run()
3.子類無法覆蓋父類__開頭的屬性
class A: def __init__(self, name, life): self.__name = name self.__life = life def __run(self):print(‘run‘) def sing(self): self.__run() print(‘sing‘) class B(A): def __init__(self, name, age, life): super().__init__(name, age) self.__life = life def __run(self): print(‘---‘) print(A.__dict__) print(B.__dict__) 輸出結果: {‘__module__‘: ‘__main__‘, ‘__init__‘: <function A.__init__ at 0x1068190d0>, ‘_A__run‘: <function A.__run at 0x1068192f0>, {‘__module__‘: ‘__main__‘, ‘__init__‘: <function B.__init__ at 0x106819730>, ‘_B__run‘: <function B.__run at 0x1068197b8>, 兩個run方法的屬性是不一樣的。
方法和屬性隱藏需要註意的地方:
1.外部不能直接飲用,需要對象._類__屬性的形式可以提出隱藏的屬性和方法
2.變形的過程只有在類的定義時發生一次,再次賦值時不會變形。
3.在繼承中,如果父類不想讓子類覆蓋自己的方法,可以將方法定義為私有的。
1.外部不能直接飲用,需要對象._類__屬性的形式可以提出隱藏的屬性和方法
class A: def __init__(self, name, life): self.__name = name self.__life = life def __run(self): print(‘run‘) def sing(self): self.__run() print(‘sing‘) a = A(‘gaohui‘, 100) print(a._A__name) 輸出結果: gaohui
2.變形的過程只有在類的定義時發生一次,再次賦值時不會變形。
class A: def __init__(self, name, life): self.__name = name self.__life = life def __run(self): print(‘run‘) def sing(self): self.__run() print(‘sing‘) A.__b = 1 a = A(‘gaohui‘, 100) print(a._A__name) print(A.__b) 輸出結果: gaohui 1
當類已經定義好了,再次定義時不會變形成隱藏的模式。
3.在繼承中,如果父類不想讓子類覆蓋自己的方法,可以將方法定義為私有的。
class A: def __fa(self): *_A__fa print(‘from A‘) def test(self): self.__fa() # 此時的fa方法是變形過的_A__fa,所以之行類A中的fa方法 class B(A): def __fa(self): *_B__fa print(‘from B‘) b = B() b.test() 輸出結果: from A
封裝數據屬性的意義:明確的區分內外,控制外部對隱藏的屬性的操作行為
class A: def __init__(self, name, age): self.__name = name self.__age = age def tell_info(self): # 可以通過一個接口來顯示被隱藏的數據,不能直接被外部調用 print(‘name is %s, age is %s‘ % (self.__name, self.__age)) def search_info(self, name, age): if not isinstance(name, str): # 檢驗是不是字符串 print(‘姓名為字符串‘) return if not isinstance(age, int): print(‘年齡已經為整數‘) return self.__name = name self.__age = age self.tell_info() st = A(‘GAO‘, 23) print(st.__dict__) #st.search_info(‘Gww‘, 23) # 可以通過一個接口來修改name和age,而不是直接修改
封裝方法:
class ATM: def __card(self): print(‘插卡‘) def __auth(self): print(‘用戶驗證‘) def __input(self): print(‘輸入取款金額‘) def withdraw(self): self.__card() self.__auth() self.__input() a = ATM() a.withdraw()
封裝之如何隱藏對象及封裝的意義