四周二次課(11月7日)
一、 類的重寫
1.1 重寫一般方法
class A: def hello(self): print('Hello,i am A.') class B(A): pass a = A() b = B() a.hello() b.hello()
結果:
Hello,i am A. Hello,i am A.
解釋:
B類沒有定義自己的hello方法,故當hello被調用時,原始信息就被打印出來了。
B類也可以重寫這個hello方法
class A: def hello(self): print('Hello,i am A.') class B(A): def hello(self): print('Hello,i am B.') a = A() b = B() a.hello() b.hello()
結果:
Hello,i am A. Hello,i am B.
1.2 重寫特殊的構造方法
1、調用未綁定的基類構造方法
class Bird: def __init__(self): self.hungry = True def eat(self): if self.hungry: print('Aaaah...') self.hungry = False else: print('No,thanks!') class SongBird(Bird): def __init__(self): Bird.__init__(self) self.sound = 'Squawk!' def sing(self): print(self.sound) b = SongBird() b.sing() b.eat() b.eat()
結果:
Squawk! Aaaah... No,thanks!
2、使用super函數
class Bird(): def __init__(self): self.hungry = True def eat(self): if self.hungry: print('Aaaah...') self.hungry = False else: print('No,thanks!') class SongBird(Bird): def __init__(self): super(SongBird,self).__init__() self.sound = 'Squawk!' def sing(self): print(self.sound) b = SongBird() b.sing() b.eat() b.eat()
結果:
Squawk! Aaaah... No,thanks!
解釋:
Python 2中定義類需要寫上object,否則報錯。
二、類的私有變量
在Python中可以通過在屬性變量名前加上雙下劃線定義屬性爲私有屬性
特殊變量命名
1、 _xx 以單下劃線開頭的表示的是protected類型的變量。即保護類型只能允許其本身與子類進行訪問。若內部變量標示,如: 當使用“from M import”時,不會將以一個下劃線開頭的對象引入 。
2、 __xx 雙下劃線的表示的是私有類型的變量。只能允許這個類本身進行訪問了,連子類也不可以用於命名一個類屬性(類變量),調用時名字被改變(在類FooBar內部,__boo變成_FooBar__boo,如self._FooBar__boo)
3、 __xx__定義的是特殊方法。用戶控制的命名空間內的變量或是屬性,如init , __import__或是file 。只有當文檔有說明時使用,不要自己定義這類變量。 (就是說這些是python內部定義的變量名)
在這裏強調說一下私有變量,python默認的成員函數和成員變量都是公開的,沒有像其他類似語言的public,private等關鍵字修飾.但是可以在變量前面加上兩個下劃線"_",這樣的話函數或變量就變成私有的.這是python的私有變量軋壓(這個翻譯好拗口),英文是(private name mangling.) **情況就是當變量被標記爲私有後,在變量的前端插入類名,再類名前添加一個下劃線"_",即形成了_ClassName__變量名.**
Python內置類屬性
__dict__ : 類的屬性(包含一個字典,由類的數據屬性組成)
__doc__ :類的文檔字符串
__module__: 類定義所在的模塊(類的全名是'__main__.className',如果類位於一個導入模塊mymod中,那麼className.__module__ 等於 mymod)
__bases__ : 類的所有父類構成元素(包含了一個由所有父類組成的元組)
例子1:
class A(object):
def __init__(self):
self.__data = [] # 翻譯成 self._A__data=[]
def add(self, item):
self.__data.append(item) # 翻譯成 self._A__data.append(item)
def printData(self):
print self.__data # 翻譯成 self._A__data
a = A()
a.add('hello')
a.add('python')
a.printData()
# print a.__data #外界不能訪問私有變量 AttributeError: 'A' object has no attribute '__data'
print a._A__data # 通過這種方式,在外面也能夠訪問“私有”變量;這一點在調試中是比較有用的!
結果:
['hello', 'python']
['hello', 'python']
例子2:
class A(): def __init__(self): self.__name = 'python' # 私有變量,翻譯成 self._A__name='python' def __say(self): # 私有方法,翻譯成 def _A__say(self) print self.__name # 翻譯成 self._A__name a = A() # print a.__name #訪問私有屬性,報錯!AttributeError: A instance has no attribute '__name' print a.__dict__ # 查詢出實例a的屬性的集合 print a._A__name # 這樣,就可以訪問私有變量了 # a.__say()#調用私有方法,報錯。AttributeError: A instance has no attribute '__say' print dir(a) # 獲取實例的所有屬性和方法 a._A__say() # 這樣,就可以調用私有方法了
結果:
{'_A__name': 'python'} python ['_A__name', '_A__say', '__doc__', '__init__', '__module__'] python