12-python基礎知識-面向物件
阿新 • • 發佈:2018-12-28
面向物件
抽象基類(瞭解)
-
說明:
- 抽象基類就是為了統一介面而存在的
- 抽象類不能進行例項化(建立物件)
- 繼承自抽象類的子類必須實現抽象類中的抽象方法
-
示例:
from abc import ABC, abstractmethod # 抽象基類 class Animal(ABC): # 定義抽象方法:規定介面 @abstractmethod def run(self): pass # 抽象基類無法例項化 # a = Animal()
特殊函式
-
示例1
d = {'name': 'xiaoming', 'age': 20} # 返回物件的字串表示形式 r = repr(d) print(r, type(r)) # 執行有效的python程式碼字串 d2 = eval(r) print(d2, type(d2)) a = 10 b = 20 c = eval
-
示例2:
class Person: def __init__(self, name, age): self.name = name self.age = age # print列印物件,str方法轉換時都會觸發 def __str__(self): print('__str__') return '姓名:{} 年齡:{}'.format(self.name, self.age) # 返回物件的字串表示形式,使用repr函式處理時會自動觸發 def
內建方法
-
構造和析構
__init__、__del____
-
干預屬性操作
__setattr__、__getattr__、__delattr__
-
支援字典操作
__setitem__、__getitem__、__delitem__
-
物件支援函式呼叫
__call__
-
列印輸出或str轉換
__str__
-
物件的字串表示,呼叫repr方法時觸發
__repr__
運算子過載
-
算術運算子
- 示例:
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__') # 返回新的Number物件 # return Number(self.num + other) # 返回處理後的原始物件 self.num += other return self n = Number(10) print(id(n)) # ret = n + 20 # ret = 20 + n # print(ret) n += 50 # n = n + 50 print(id(n))
- 自行測試
加法:add、radd、iadd 減法:sub、rsub、isub 乘法:mul、rmul、imul 除法:truediv、rtruediv、itruediv 求餘:mod、rmod、imod
-
關係運算符
class Number: def __init__(self, num): self.num = num # 大於 > def __gt__(self, other): print('__gt__') return self.num > other # 小於 < def __lt__(self, other): print('__lt__') return self.num < other # 等於 ==, 判斷是否相等,當不實現__ne__時,!=運算也會觸發 def __eq__(self, other): print('__eq__') return self.num == other # 大於等於 >= def __ge__(self, other): print('__ge__') return self.num >= other # 小於等於 <= def __le__(self, other): print('__le__') return self.num <= other # 不等於 != def __ne__(self, other): print('__ne__') return self.num != other n = Number(20) print(n > 10) print(n < 10) print(n == 10) print(n != 10)
記憶體管理
-
引用計數
- python中所有的資料都是通過類來實現的,物件的管理是通過引用計數實現的
- 當建立一個物件賦值給一個變數時,引用計數為1,當多一個變數指向該物件時,計數值加1;當少一個變數指向物件時,計數值減1。計數值減到0時會呼叫
__del__
方法釋放儲存空間 - 不可變變數引用計數是沒有意義的
- 示例:
import sys # 不可變變數的引用計數沒有意義 a = 10 print(sys.getrefcount(a)) lt = [1, 2, 3] lt2 = lt # 本身此時引用計數為1,但是該方法也引用了一次 print(sys.getrefcount(lt)) del lt2 print(sys.getrefcount(lt)) class Person: def __del__(self): print('物件即將釋放') p = Person() print(sys.getrefcount(p)) del p print('over')
-
函式傳參
- 對不可變變數來說,傳遞的是值,函式中不可能改變傳遞的引數
- 對於可變變數及自定義的類建立的物件,傳遞的是引用,函式中可以操作原物件
- 示例:
def test(a): a += 1 num = 100 # 對於不可變資料傳遞的是值 test(num) print(num) def test2(lt): lt[0] = 10 lt = [1, 2, 3] test2(lt) print(lt)
-
深淺拷貝
import copy lt = [1, 2, [3, 4]] # 賦值會增加一個引用,訪問的都是同一資料 lt2 = lt # 淺拷貝:只拷貝物件本身,裡面的元素只會增加一個引用 # lt2 = lt.copy() # 專門的拷貝函式,也是淺拷貝,等價於上面的拷貝 lt2 = copy.copy(lt) # 深拷貝:拷貝物件本身,物件中的元素也進行拷貝 # lt2 = copy.deepcopy(lt) lt[0] = 100 lt2 = 30 print(lt) print(lt2) print(id(lt)) print(id(lt2)) # 判斷是否是同一物件的多個引用 print(lt is lt2)
資料持久化儲存
-
說明:持久化儲存方案,普通檔案、資料庫、序列化
-
示例:
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) # print(xiaoming) # 序列化:會將物件轉換為bytes # s = pickle.dumps(xiaoming) # print(s) # 反序列化:從bytes中解析出物件 # xm = pickle.loads(s) # print(xm, type(xm)) # 直接儲存到檔案 # fp = open('data.txt', 'wb') # pickle.dump(xiaoming, fp) # fp.close() # 從檔案中讀取物件 fp = open('data.txt', 'rb') xm = pickle.load(fp) print(xm, type(xm))