學習筆記Python篇~面向對象

面向對象

  • 用面向對象的思維去解決問題。
  • 將某一類事物相關的屬性和方法封裝在一起,用來表示這類事物
  • 面向對象,借鑑函數的封裝思維,再次對函數和變量進行封裝,來提高代碼的複用性

class 使用class關鍵字定義類

  • 為了便於區分,把用關鍵字 class 定義的代碼塊稱為 類
  • 命名時使用峰駝命名法,即首字母大寫
  • 在類裡面的變量稱為 類的屬性
  • 在類裡面的函數稱為 類的方法
  • self 是實例自己
  • __init__ 是初始化函數,在實例化時會自動調用
  • 實例通過點(.)操作來調用屬性或者方法

類的析構函數

  • 在類中增加__del__函數,當刪除實例的時候,就會調用此方法
  • del關鍵字用來刪除對象
  • 案例:
<code>class Person: #定義一個類
\tdef __init__(self,name,age,sex='男'):#初始化實例函數
\t\tself.name = name
\t\tself.age = age
\t\tself.sex = sex
\tdef paly(self):
\t\tprint(f'{self.name}正在玩遊戲!')

\tdef search(self):
\t\tprint(f'{self.name}正在查找資料')

\tdef __del__(self):
\t\tprint(f'{self.name}事情做完了')

morang = Person('莫讓龍',18) #實例化對象
morang.name #調用實例化對象的屬性
morang.play() #調用實例化對象的方法
del morang #刪除實例化對象/<code>

繼承和重用

  • 繼承:
  • 所有的類都繼承與object
  • 通過繼承可以很好的提高代碼的複用性
  • 通過在類後面的跟上要繼承的類來確定父類
  • 多繼承時,只需要在繼承時增加需要繼承的類即可
  • __base__ 調用時,可以看到繼承的第一個類
  • __bases__ 調用時,可以查看繼承的所有類
  • mro 方法查看繼承順序
  • 重用:
  • 子類重新定義父類方法,讓同一方法有不同的行為
  • 如果子類想繼續使用父類的行為,推薦使用super函數方法來實現

mix-in 設計模式 基於多繼承的方式的

常用內置函數

  • 1、屬性訪問函數
  • hasattr(a,'b') 判斷a裡有沒有b屬性
  • getattr(a,'b') 獲取a裡面b屬性的值
  • setattr(a,'b','c') 設置 a裡面b屬性的值為 c (有則改,無則增加)
  • delattr(a,'b') 刪除a裡的b屬性
  • 注意:屬性名需要加上引號attr即attribute的縮寫
  • 三目運算確保f得到屬性值:
<code>f = getattr(a,'b') if hasattr(a,'b') else setattr(a,'b','c')/<code>
  • 2、對象關係方法
  • issupclass(a,b) 判斷a是不是b的子類
  • isinstance(a,b) 判斷實例a是不是b的實例
  • isinstance 多用於判斷類型 :
  • isinstance(a,int) 判斷a是不是int類型
  • isinstance(a,(int,float)) 判斷a是不是int或者float類型
  • type 也可以判斷,但是隻能判斷單個類,一般很少使用
  • 3、魔法方法
  • Python中很多內置方法都是兩個下劃線在兩邊,中間是單詞名字,並且這樣的方法名字有一定的特殊的含義,把這種方法都稱之為魔法方法
  • __new__方法,就是最開始調用的一個方法,會在初始化之前自動調用
  • 例如:def __new__(cls,*args,**kwargs): #cls 類本身
  • 單例模式:類始終只有一個實例存在,不會同時出現多個實例
<code>def __new__(cls,*args,**kwargs):
\tif not hasattr(cls,'_instance'):
\t\tcls._instance = super().__new__(cls)
\t\treturn cls._instance/<code>

利用__new__方法,可以很方便的去實現一個類的單例模式

  • 4、輸出魔法方法
  • __str__ 修改print打印時的樣子
  • __repr__ 修改直接打印時的樣子
  • __call__ 讓實例化對象向函數一樣去使用
  • 例如:
<code>def __str__(self):
\treturn 'this is str %s' %self.name
def __repr__(self):
\treturn 'this is repr %r' %self.name
def __call__(self,num):
\tnum = num*10

\tprint(num)/<code>
  • 5、協議
  • Python中有很多的協議,比如序列協議等很多協議,只要遵守這些協議,既可以說是對應的類型,比如定義了序列類型協議,則定義的類就是序列類型
  • (1)序列協議
  • __len__, __getitem__,__setitem__,__delitem__等協議,如果不需要改變,那後兩個就不要定義。
<code>class IndexTuple:
\tdef __init__(self,*args):
\t\tself.values = tuple(i for i in *args)
\t\tself.index = tuple(enumerate(self.values))#enumerate 枚舉方法

\tdef __len__(self):
\t\treturn len(self.values)

\tdef __getitem__(self,key):
\t\treturn self.index[key][1]

\tdef __repr__(self):
\t\treturn str(self.values) #repr 需要返回字符串模式/<code>
  • (2)迭代器協議
  • 只要類實現了__iter__ 和 __next__ 方法,則這個類就是迭代器,因此只要實現這兩個方法,則是可以迭代對象
<code>class Number:
\tdef _init__(self,end=10):
\t\tself.start = 0

\t\tself.end = end
\tdef __iter__(self):
\t\treturn self
\tdef __next__(self):
\t\tself.start += 1
\t\tif self.start >= self.end:
\t\t\traise StopIteration
\t\treturn self.start/<code>
  • (3)上下文協議
  • 只要類裡面定義__enter__和__exit__這兩個方法,則可以使用with去使用此對象
  • 案例:計算函數運行的時間
<code>import time
class RunTime:
\tdef __enter__(self):
\t\tself.start_time = time.time()
\t\treturn self.start_time

\tdef __exit__(self,exc_type,exc_val,exc_tb):
#exc_type、exc_val、exc_tb 固定三個參數必須寫,應用時可以不傳值
\t\tself.end_time = time.time()
\t\tself.run_time = self.end_time -self.start_time
\t\tprint('運行時間為%s' %self.run_time)/<code>


分享到:


相關文章: