38 環境管理器:
Ø 類內有__enter__ 和 __exit__方法的類,被稱為環境管理器
Ø 能夠用with語句進行管理的對象必須是環境管理器
Ø __enter__將在進入with語句時被調用並返回由as變數管理的對象
Ø __exit__將在離開with時被調用,且可以用參數來判斷在離開with語句時是否有異常發生,並做出相應的處理 38.1 樣本
class Cooker: def open_gas(self): print("開啟天然氣") def close_gas(self): print("關閉天然氣") def dowork(self): print("製作燒餅") def __enter__(self):
self.open_gas()
return self
def __exit__(self, exc_type, exc_value, exc_tb):
self.close_gas() if exc_type is None: print("正常離開") else: print("異常退出")
with Cooker() as c: c.dowork() |
39 編碼規範
PEP8編碼規範
建立多個對象,而且都有自己的名字空間,這樣不會產生衝突
繼承,封裝,多態 40 繼承(inheritance)和派生(derived) 40.1繼承的目的
繼承的目的延續舊的功能
派生的目的在舊的功能之上添加新的功能 40.2 作用
用繼承派生機制,可以將一些共有功能載入基類上,實現代碼共用,在不改變超類的代碼的基礎上改變原有功能
基類(base class) /超類(super class) /父類(father class)
衍生類別(derivedclass)/子類(child class) 40.3 單繼承文法:
class 類名(超類名):
······· 40.4 繼承說明:
任何類都直接或間接的繼承自object類
object類是一切類的超類 40.5 __base__屬性
作用:
用來記錄此類的基類(類執行個體)
import human class Student(human.Human): pass s1 = Student() print(s1.__class__.__base__()) #<human.Human object at 0x7f15d106a7b8> print(s1.__class__.__base__) # <class 'human.Human'> print(s1.__class__.__base__.__base__) # <class 'object'> print(Student.__base__) # <class 'human.Human'> print(Student.__base__.__base__) # <class 'object'> print(object.__base__) # None |
40.6 覆蓋 override(重寫 overwrite)
什麼是覆蓋
覆蓋是指有繼承關係的類中,子類中實現了與基類同名的方法,在子類執行個體調用該方法時,實際調用的是子類中覆蓋的版本,這種現象叫做覆蓋
子類對象顯示調用基類方法的方式
基類名.方法名(對象,參數) #先調用子類,如果沒有再找基類
執行個體.方法名(參數) #此時執行個體調用的是子類自己的方法(如果子類中有該方法名) 40.7 super函數
Ø super(type,obj) 返回綁定超類的執行個體(要求obj必須為type類型的執行個體)
Ø super()返回綁定的超類的執行個體,等同於(class,執行個體方法的第一個參數),此方法必須用在方法內部 40.7.1 作用:
返回綁定超類的執行個體,用超類的執行個體來調用其自身的方法 40.7.2 樣本
class A: def hello(slef): print('A類中的hello(self)') class B(A): def hello(self): print("B類種的hello")
base = B() base.hello() # B類種的hello super(B, base).hello() # A類中的hello(self) 等同於 B.__base__.hello(base) #類名.方法名(執行個體,參數) |
class A: def hello(slef): print('A類中的hello(self)') class B(A): def hello(self): print("B類種的hello") def super_hello(self): self.hello() super(B,self).hello() super().hello() base = B() base.hello() # B類種的hello super(B, base).hello() # A類中的hello(self) 等同於 B.__base__.hello(base) base.super_hello() B類種的hello A類中的hello(self) B類種的hello A類中的hello(self) A類中的hello(self) |
41用與類的函數
issubclass(cls,類或類元組)
判斷一個類是否是繼承自其它的類,如果此類cls是類(class)或元組中的一個衍生類別則返回True,否則返回False
class A: pass class B(A): pass class C(B): pass class D(C): pass print(issubclass(C,A)) #True print(issubclass(D,B)) # True print(issubclass(D,A)) #True print(issubclass(bool,int)) #True print(issubclass(bool,float)) #False |
42 顯示調用基類的構造方法:
def__init__(self,·········):
············
樣本 class Human(object): """docstring for ClassName""" def __init__(self, name, age): self.name = name self.age = age def infos(self): print('name:', self.name, 'age:', self.age) class Student(Human):
def __init__(self, name, age, score): super(Student, self).__init__(name, age) # self.name = name # self.age = age self.score = score def infos(self): print("name", self.name, 'age', self.age, 'score:', self.score) h1 = Human("張珊", 18) h1.infos() s1 = Student('小玲', 20, 99) s1.infos() name: 張珊 age: 18 name 小玲 age 20 score: 99 |
43 多態 polymorphic
43.1 定義
字面意思是‘多種狀態’
多態是在有繼承/派生關係的類中,調用基類對象的方法,實際能調用子類的覆蓋方法的現象
多態調用的方法與對象相關,不與類型相關
class Shape: def draw(self): self.drawSelf() class Point(Shape): def drawSelf(self): print("❀個鳥") class Circle(Point): def drawSelf(self): print("畫個圓") shape = Point() shape.draw() #❀個鳥 shape = Circle() shape.draw() #畫個圓 |
44 物件導向思想的特徵:
1 封裝
2 繼承(派生)
3 多態 (由於此特徵,可以使列表存放多種資料類型) 45 封裝:enclosure 45.1 作用
封裝是指隱藏類的實現細節,讓使用者不關心這些細節
註:python的封裝是假的(類比)封裝 45.2 私人執行個體變數和方法:
Python類中,以雙底線'__'開頭,不以雙底線結尾的表示符為私人成員
私人成員分為:
私人屬性和私人方法
私人成員在子類和類外部無法訪問
class A: def __init__(self, args): self.__p = args def showA(self): print("self.__p:", self.__p)
a = A(100) a.showA() print(a.__p) 執行結果 self.__p: 100 Traceback (most recent call last): File "enclosure.py", line 12, in <module> print(a.__p) AttributeError: 'A' object has no attribute '__p' |
class A: def __init__(self, args): self.__p = args def showA(self): return self.__p
a = A(100) print(a.showA()) #100 可以拿到值 |
46 多繼承 multiple inheritance
多繼承是指一個子類繼承兩個或兩個以上的基類 46.1 多繼承的文法:
class 類名(超類名1,超類名2···········):
···········
class Car: def run(self, speed): print("汽車以", speed, 'km/h速度行駛') class Plane: def fly(self, height): print("在海拔", height, '米上空飛行') class PlaneCar(Car, Plane): '''PlaneCar類同時繼承飛機和汽車 沒有pass,什麼也沒寫 ''' pl = PlaneCar() pl.fly(20000) #在海拔 20000 米上空飛行 pl.run(600) #汽車以 600 km/h速度行駛 |
46.2 多繼承的缺陷
標識符衝突的問題
要謹慎使用多繼承
class A: def __init__(self): self.name = 'A' class B(object): """docstring for B""" def __init__(self): self.name = 'B' class AB(A, B): #換成(B,A) 結果是B def infos(self): print(self.name) ab = AB() ab.infos() #A |