1. 程式人生 > >Python學習(7)——面向物件高階編輯

Python學習(7)——面向物件高階編輯

1、使用__slots__

(1)可以嘗試給例項繫結一個方法:

def set_age(self, age):
    self.age = age
from types import MethodType
s.set_age = MethodType(set_age, s) # 給例項繫結一個方法

(2)但是,給一個例項繫結的方法,對另一個例項是不起作用的

(3)為了給所有例項都繫結方法,可以給class繫結方法:

def set_score(self, score):
     self.score = score
Student.set_score = set_score

(4)Python允許在定義class的時候,定義一個特殊的__slots__變數,來限制該class例項能新增的屬性

(5)__slots__定義的屬性僅對當前類例項起作用,對繼承的子類不起作用

(6)子類例項允許定義的屬性就是自身的__slots__加上父類的__slots__

 

2、使用@property

(1)對於類的方法,裝飾器一樣起作用。Python內建的@property裝飾器就是負責把一個方法變成屬性呼叫的

(2)還可以定義只讀屬性,只定義getter方法,不定義setter方法就是一個只讀屬性

 

3、多重繼承

(1)MixIn有點類似於Object-C的protocol,但MixIn是類,有可呼叫的方法和屬性

(2)Python允許使用多重繼承

 

4、定製類

(1)__len__()方法是為了能讓class作用於len()函式

(2)定義__str__()方法,返回一個好看的字串,print(s)可以呼叫到例項s的__str__方法

(3)__str__()返回使用者看到的字串,而__repr__()返回程式開發者看到的字串

(4)通常__str__()__repr__()程式碼都是一樣的,所以,有個偷懶的寫法:__repr__ = __str__

(5)一個類想被用於for ... in迴圈,就必須實現一個__iter__()方法,該方法返回一個迭代物件,Python的for迴圈就會不斷呼叫該迭代物件的__next__()

方法拿到迴圈的下一個值,直到遇到StopIteration錯誤時退出迴圈:raise StopIteration()

(6)要表現得像list那樣按照下標取出元素,需要實現__getitem__()方法

(7)__getitem__()傳入的引數可能是一個int,也可能是一個切片物件slice

(8)如果把物件看成dict__getitem__()的引數也可能是一個可以作key的object;與之對應的是__setitem__()方法,把物件視作list或dict來對集合賦值

(9)還有一個__delitem__()方法,用於刪除某個元素

(10)呼叫不存在的屬性時,Python直譯器會試圖呼叫__getattr__(self, 'xxx')來嘗試獲得屬性(REST API,鏈式呼叫)

(11)任何類,只需要定義一個__call__()方法,就可以直接對例項進行呼叫

(12)能被呼叫的物件就是一個Callable物件,比如函式和帶有__call__()的類例項,通過callable()函式,我們就可以判斷一個物件是否是“可呼叫”物件:callable([1, 2, 3])

    還有很多可定製的方法,請參考Python的官方文件

 

5、使用列舉類

(1)為列舉型別定義一個class型別,每個常量都是class的一個唯一例項。Python提供了Enum類來實現這個功能:

from enum import Enum
Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))

        可以直接使用Month.Jan來引用一個常量,或者列舉它的所有成員:

for name, member in Month.__members__.items():
    print(name, '=>', member, ',', member.value)

        value屬性則是自動賦給成員的int常量,預設從1開始計數。

(2)如果需要更精確地控制列舉型別,可以從Enum派生出自定義類:

from enum import Enum, unique

@unique
class Weekday(Enum):
    Sun = 0 # Sun的value被設定為0
    Mon = 1
    Tue = 2
    Wed = 3
    Thu = 4
    Fri = 5
    Sat = 6

        @unique裝飾器可以幫助我們檢查保證沒有重複值

 

6、使用元類

(1)type()函式可以檢視一個型別或變數的型別,class的型別是type

(2)可以通過type()函式創建出Hello類,而無需通過class Hello(object)...的定義

(3)要建立一個class物件,type()函式依次傳入3個引數:

  1. class的名稱;
  2. 繼承的父類集合,注意Python支援多重繼承,如果只有一個父類,別忘了tuple的單元素寫法;
  3. class的方法名稱與函式繫結,這裡我們把函式fn繫結到方法名hello上。

(4)metaclass,直譯為元類

        先定義metaclass,就可以建立類,最後建立例項(ORM)

https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/0014319106919344c4ef8b1e04c48778bb45796e0335839000