面對對象&異常&子產品
一 . 工廠模式
解耦: 降低耦合
def order(self,car_type):
class Store(object):
#工廠方法模式 : 在接口定義抽象方法 在子類中實作
def select_car(self):
pass
def order(self,car_type):
return self.select_car(car_type)
class BMWCarStore(Store):
def select_car(self,car_type):
return BMWFactory().select_car_by_type(car_type)
bmw_store = BMWCarStore()
bmw = bmw_store.order("720li")
class CarStore(Store):
def select_car(self,car_type):
return Factory().select_car_by_type(car_type)
class BMWFactory(object):
def select_car_by_type(self,car_type):
pass
if car_type = "720li":
return Mingtu()
elif car_type == 'Ix35':
return Ix35()
elif car_type == "mini":
return Sounata()
if car_type == 'mini':
return Suonata()
elif car_type == '720li':
return Mingtu()
elif car_type == 'x6':
return Ix35()
class Factory(object):
#解耦 工廠模式
def select_car_by_type(car_type):
return Fute()
if(car_type=="桑塔納"):
return Santana()
elif car_type=="福特":
class Car(object):
def move(self):
print("車在移動...")
def music(self):
print("正在播放音樂")
def stop(self):
print("車已停止")
class Santana(Car):
pass
class Fute(Car):
pass
class Mingtu(Car):
pass
class Suonata(Car):
pass
class Ix35(Car):
pass
car_store = CarStore()
car =car_store.order("桑塔納")
car.move()
car.music()
定義一個建立對象的接口(可以了解為函數),但由子類決定要執行個體化的類是哪個,
工廠方法的執行個體化推遲到子類,抽象的CarStore提供了一個建立createCar,也叫做工廠方法
子類真正實作這個createCar方法建立出具體産品.i建立者類不需要直到實際建立的産品是哪一個,選擇
了使用了那個子類,自然也就決定了實際建立的産品是什麼.
二 . __new__
方法
__new__
class A (object):
"""docstring for ."""
def __init__(self):
print('這是init方法')
def __new__(cls):
print("這是new方法")
return object.__new__(cls)
a = A()
-
至少要一個參數cls,代表要執行個體化的類,此參數在執行個體化時Python解釋器自動提供__new__
-
必須有傳回值,傳回值執行個體化出來的執行個體,這點在自己實作__new__
時要特别注意,可以return父類__new__
出來的執行個體,或者直接object的__new__
出來的執行個體__new__
-
有一個參數self,就是這個__init__
傳回的執行個體,__new__
在__init__
的基礎上可以完成一些其他初始化的動作,__new__
不需要傳回值__init__
- 我們将類比作制造商,
方法就是前期的原材料購買環節,__new__
方法就是在有原材料的基礎上,加工初始化商品環節.__init__
a= A()
相當于做了三件事:
- 1.調用
__new__
方法建立對象,然後找一個變量來接收
__new__
的傳回值,這個傳回值表示建立出來的對象的引用
- 2.
__init__(剛剛建立出來的對象的應用)
- 3.傳回對象的引用
注意:
__init__
方法不等于構造方法
__init__
隻負責初始化
__new___
隻負責建立
兩者結合==構造方法
三 單例模式
隻能建立同一對象的類
# 執行個體化一個單例
class Singleton(object):
__instance = None
__first_init = False
def __new__(cls, age, name):
#隻産生同一對象
if cls.__instance == None:
cls.__instance = object.__new__(cls)
return cls.__instance
def __init__(self, age, name):
#隻初始化一次
if self.__first_init == False:
self.name = name
self.age = age
self.__first_init == True
a = Singleton(, "longge")
b = Singleton(, "long")
print(id(a))
print(id(b))
print(a.age)
print(b.age)
四 捕獲異常
<1> 捕獲異常 try…except..
try:
pass #可能會出異常的操作
except IOError:
pass #異常處理
<2> except 捕獲多個異常
try:
open("123.txt","r") # 檔案不存在産生錯誤
print num #num 未定義産生錯誤
except IOError
print('産生錯誤')
還會産生錯誤 ,問題不止一個
try:
open("123.txt","r") # 檔案不存在産生錯誤
print num #num 未定義産生錯誤
except (IOError,NameError): #捕獲多個異常使用元組 将可能産生的異常的名字解除安裝except 後 并使用元組方式存儲
print(errorMsg) #errorMsg儲存捕獲到的錯誤資訊
<3> 捕獲所有異常
# 不存儲異常的基本資訊
try:
open("123.txt","r") # 檔案不存在産生錯誤
print num #num 未定義産生錯誤
except :
print('産生錯誤')
# 捕獲所有異常,并存儲異常基本資訊
try:
open("123.txt","r") # 檔案不存在産生錯誤
print num #num 未定義産生錯誤
except Exception as result:
print('産生錯誤')
else:
print('沒有産生異常')
<6> try…finally
用來處理必須的執行,無論是否産生異常 eg:檔案關閉,釋放鎖,把資料庫進行連結返還給連結池等
try:
f = open("test")
while True:
content = f.readLine()
if len(content)==:
break
time.sleep()
print(content)
finally:
f.close()
print('關閉檔案')
五 傳遞異常
def test1():
print("----test1----")
open('num')
print("----test1---2-")
def test2():
print("----test2----")
test1()
print("----test2---2-")
def test3():
try:
print("----test3----1")
test1()
print("----test3----2")
except Exception as result:
print('捕獲所有異常:%s'%result)
print("----test3----3")
test3()
print("-------------------")
test2()
異常: test1 (産生異常,不處理)—->test3 ( 處理異常,未傳回test1)
—–>test2 (未處理異常,繼續傳遞,所有都沒處理,進行預設異常處理)
<六> 抛出自定義異常
可用raise 語句引發一個異常, 異常/錯誤對象必須有一個名字,且它們應是Error或Exception類的子類
class ShortInputException(Exception):
'''自定異常類'''
def __init__(self ,length,atleast):
#super.__init__()
self.length = length
self.atleast = atleast
try:
s = input('請輸入-->')
if len(s) < :
#raise 引發一個自定的異常
raise ShortInputException(len(s),)
except EOFError:
print('你輸入了結束标志EOF')
except ShortInputException as result:
print('ShortInputException:輸入長度是%d,長度應為 %d'%(result.length,result.atleast))
else:
print('沒有異常發生')
注意: #super().init() 可調用可不調用,建議調用,因為init方法往往是用來對建立完的對象進行初始化工作,
如果在子類中重寫父類的init方法意味着父類中的很多初始化工作沒有做,不能保證程式的穩定,
重寫init方法做好先調用父類該方法,再添加自己的功能
七 異常中抛出異常
class Test(object):
def __init__(self,switch):
self.switch =switch
def calc(self,a,b):
try:
return a/b
except Exception as result:
if self.switch:
print('捕獲開啟,已經捕獲異常,資訊如下:')
print(result)
else:
#重新抛出此異常,并且不會被這個異常處理捕獲,出發預設異常處理
raise
a = Test(True)
a.calc(,)
print('--------------從天而降割線------------------')
a.switch =False
a.calc(,)