天天看點

12-面對對象&異常面對對象&異常&子產品

面對對象&異常&子產品

一 . 工廠模式

解耦: 降低耦合

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__

方法

class A (object):
    """docstring for ."""
    def __init__(self):
        print('這是init方法')

    def __new__(cls):
        print("這是new方法")
        return object.__new__(cls)



a = A()
           
  • __new__

    至少要一個參數cls,代表要執行個體化的類,此參數在執行個體化時Python解釋器自動提供
  • __new__

    必須有傳回值,傳回值執行個體化出來的執行個體,這點在自己實作

    __new__

    時要特别注意,可以return父類

    __new__

    出來的執行個體,或者直接object的

    __new__

    出來的執行個體
  • __init__

    有一個參數self,就是這個

    __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(,)