1. 程式人生 > >13-面向物件及異常處理

13-面向物件及異常處理

面向物件及異常處理

內建函式

  • 總結:__init__、__del__、__str__、attr系列、item系列、__call__

  • __str__與__repr__

    • 使用print/str方法時會自動觸發__str__方法,當__str__不存在,嘗試__repr__
    • 使用repr方法時會自動觸發__repr__方法
    • repr方法通常用於返回物件的字串表示形式
    • 這兩個方法都只能返回字串
    • eval方法可以將一個字串當做有效的程式碼執行
  • 算術運算子過載

    • 示例:
    class Number:
        def __init__(self, num):
            self.num 
    = num # 物件出現在'+'左邊時會自動觸發 def __add__(self, other): print('__add__') return self.num + other # 物件出現在'+'右邊是會自動觸發 def __radd__(self, other): print('__radd__') return self.num + other # +=運算時會自動觸發,沒有時會觸發 __add__ def __iadd__(self, other):
    print('__iadd__') return Number(self.num + other) n = Number(100) ret = n + 200 ret = 200 + n print(ret) n += 200 # n = n + 200 print(n)
    • 自己測試
    加法:__add____radd____iadd__
    減法:__sub____rsub____isub__
    乘法:__mul____rmul____imul__
    除法:__truediv____rtruediv____itruediv__
    求餘:__mod__rmod____imod__
  • 關係運算符過載

    >:        __gt__
    =:        __ge__
    <:        __lt__
    <=:       __le__
    ==:       __eq__
    !=:       __ne__
  • 示例

     class Number:
          def __init__(self, num):
              self.num = num
    
          def __gt__(self, other):
              print('__gt__')
              return self.num > 200
    
          def __lt__(self, other):
              print('__lt__')
              return self.num < other
    
          def __eq__(self, other):
              print('__eq__')
              return self.num == other
    
          # 當沒有此方法時,使用!=也會觸發__eq__方法
          def __ne__(self, other):
              print('__ne__')
              return self.num != other
        
    n = Number(100)
    
    # print(n > 200)
    # print(200 > n)
    # print(200 == n)
    print(200 != n) 

深淺拷貝

  • 引用計數

    • python中的所有變數都是物件,物件的管理採用的時引用計數的方式
    • 當多一個變數指向物件計數值加1,當少一個變指向物件計數值減1,減到0是,釋放物件(__del__)
  • 函式傳參

    • 對於不可變的變數來說,函式中不可能改傳遞過來的變數
    • 對於可變的容器物件及自定義物件,作為函式引數傳遞時,傳遞的是引用,可以修改該物件
  • 深淺拷貝

    class Person:
        def __del__(self):
            print('物件釋放')
    
    p1 = Person()
    p2 = p1
    
    print(id(p1))
    print(id(p2))
    
    del p1
    del p2
    print('OVER')
    
    def test(m):
        # m += 1
        m[0] = 300
    
    # n = 100
    n = [100, 200]
    
    test(n)
    print(n)
    
    import copy
    
    lt = [1, 2, [3, 4]]
    
    # 淺拷貝,只拷貝物件本身,不拷貝物件中的元素
    # lt2 = lt.copy()
    # 淺拷貝
    lt2 = copy.copy(lt)
    
    # 深拷貝:不但拷貝物件本身,還拷貝物件中的元素
    lt2 = copy.deepcopy(lt)
    lt[0] = 100
    lt2 = 300
    
    print(id(lt))
    print(id(lt2))
    print(lt)
    print(lt2)

資料持久化(pickle)

  • 說明:資料持久化儲存方案,普通檔案、序列化、資料庫

  • 示例:

    import pickle
    
    class Person:
        def __init__(self, name, age):
            self.name = name
            self.age  = age
    
        def __str__(self):
            return 'name:{},age:{}'.format(self.name, self.age)
        
    xiaoming = Person('xiaoming', 20)
    # 轉換為bytes型別
    
    # s = pickle.dumps(xiaoming)
    # print(s)
    
    # 從位元組流中提取物件
    # xm = pickle.loads(s)
    
    # print(xm)
    # 儲存到檔案中
    # fp = open('data.txt', 'wb')
    
    # pickle.dump(xiaoming, fp)
    # 從檔案中獲取物件
    
    fp = open('data.txt', 'rb')
    xm = pickle.load(fp)
    print(xm)

異常處理

  • 相關概念

    • 錯誤:程式執行之前的語法問題,如:關鍵字、縮排、括號不成對等
    • 異常:在程式執行過程中出現的問題,如:未定義變數、除數為0、屬性不存在等
  • 異常處理

    • 說明:異常處理可以理解為特殊的流程控制語句,可以提高程式碼的健壯性。
  • 異常語法:

    try:
          print('正常程式碼')
          # print(a)
          3/0
      except Exception as e:
          # Exception 是所有異常的基類,此處可以捕獲所有的異常
          print('出現異常')
          print(e)
    
      print('其他內容')
  • 多個異常

    # 分類捕獲異常
    '''
    try:
        # print(a)
        # 3/0
        d = {}
        print(d['name'])
    except NameError as e:
        print('NameError:', e)
    except ZeroDivisionError as e:
        print('ZeroDivisionError:', e)
    except Exception as e:
        print('OtherError:', e)
    '''
    
    try:
        # print(a)
        # 3/0
        fp = open('123.txt')
    except (NameError, ZeroDivisionError) as e:
        # 將某些異常進行統一處理,寫在一個元組中即可
        print(e)
    except:
        print('其他異常')
  • 完整結構(else-finally)

    try:
        print('正常程式碼')
        print(a)
    except:
        # 出現異常時執行
        print('出現異常')
    else:
        # 正常結束(沒有異常)時會執行
        print('正常結束')
    finally:
        # 無論有無異常,都會執行
        print('最後執行')

    else:正常結束時執行else中的程式碼

    finally:無論有無異常,最後都執行

  • 丟擲異常:raise

    try:
        print('正常程式碼')
        # 根據業務邏輯的需要,手動丟擲異常
        raise Exception('手動丟擲的異常')
    except Exception as e:
        print('異常:', e)
    
    print('OVER')
  • 異常巢狀(try-except結構中再次使用try-except結構)

    print('我要去上班,什麼事也阻止不了我上班的腳步')
    try:
        print('我準備騎電動車')
        raise Exception('昨天晚上不知道哪個缺德的傢伙把我充電器拔了')
        print('騎車提前到達公司')
    except Exception as e:
        print(e)
        try:
            print('我準備做公交車')
            raise Exception('等了20分鐘一直沒有公交車,果斷放棄')
            print('坐公交車準時到達公司')
        except Exception as e:
            print(e)
            print('我準備打車')
            print('打車還是快,一會就到達公司')
    
    print('熱情滿滿的開始一天的工作')
  • 自定義異常類(需要繼承自官方的異常基類Exception)

    # 自定義異常類
    class MyException(Exception):
        def __init__(self, msg):
            self.msg = msg
    
        def __str__(self):
            return self.msg
    
        # 特定異常標準處理方案
        def deal(self):
            print('處理特定的自定義異常')
            
    try:
        print('正常執行')
          # 手動丟擲自定義異常
          raise MyException('出現了自定義異常')
    except MyException as e:
        print(e)
          # 呼叫方法,處理異常
          e.deal()
  • 特殊場景

    • 當我們進行檔案操作時,無論過程中是否有異常,最終我們一定得進行關閉操作
    • 使用with語句,可以保證檔案的關閉,無論中間過程是否出現異常
    # fp = open('test.txt', 'r')
      # 中間無論有無異常,最後一定得關閉檔案
      # fp.close()
    
      with open('test.txt', 'r') as fp:
          content = fp.read(5)
          print(content)
          # 此處不要考慮檔案的關閉問題,也不用是否有異常

虛擬環境

  • 為什麼使用虛擬環境?
    • 當一臺電腦上不同軟體需要依賴同一個包的不同版本時,為了進行環境隔離就出現了虛擬環境
  • 安裝工具:virtualenv
    • pip install virtualenv
  • 建立虛擬環境
    • virtualenv 虛擬環境目錄名
  • 啟用虛擬環境
    • 進入虛擬環境目錄的Scripts目錄
    • 執行:activate
  • 退出虛擬環境
    • 進入虛擬環境目錄的Scripts目錄
    • 執行:deactivate.bat
  • 冷凍一個環境依賴包
    • 執行:pip freeze > requirements.txt
  • 快速複製一個虛擬環境
    • 建立一個虛擬環境
    • 啟用虛擬環境
    • 執行:pip install -r requirements.txt