1. 程式人生 > >Python學習筆記__7.6章 使用原類

Python學習筆記__7.6章 使用原類

編程語言 Python

# 這是學習廖雪峰老師python教程的學習筆記

1、概覽

動態語言和靜態語言最大的不同,就是函數和類的定義,不是編譯時定義的,而是運行時動態創建的。

1.1type()

class的定義是運行時動態創建的,而創建class的方法就是使用type()函數。

通過type()函數創建的類和直接寫class是完全一樣的,因為Python解釋器遇到class定義時,僅僅是掃描一下class定義的語法,然後調用type()函數創建出class。

type()函數既可以返回一個對象的類型,又可以創建出新的類型,比如,我們可以通過type()函數創建出Hello類:

>>> def fn(self, name='world'): # 先定義函數

... print('Hello, %s.' % name)

...

>>> Hello = type('Hello', (object,), dict(hello=fn)) # 創建Hello class

type()函數的3個參數

  1. class的名稱;

  2. 繼承的父類集合,註意Python支持多重繼承,如果只有一個父類,別忘了tuple的單元素寫法

  3. class的方法名稱與函數綁定,這裏我們把函數fn綁定到方法名hello上。

1.2metaclass

除了使用type()動態創建類以外,要控制類的創建行為,還可以使用metaclass。

先定義metaclass,就可以創建類,最後可以創建實例

用metaclass給自定義的MyList類增加一個add方法:

# metaclass是類的模板,所以必須從`type`類型派生:

class ListMetaclass(type): # metaclass的類名總是以Metaclass結尾,以便清楚地表示這是一個metaclass

def __new__(cls, name, bases, attrs):

attrs['add'] = lambda self, value: self.append(value) # 為類創建了一個add方法

return type.__new__(cls, name, bases, attrs)

class MyList(list, metaclass=ListMetaclass): # 指示使用ListMetaclass來定制類,傳入關鍵字參數metaclass

pass

當我們傳入關鍵字參數metaclass時,魔術就生效了,它指示Python解釋器在創建MyList時,要通過ListMetaclass.__new__()來創建,在此,我們可以修改類的定義,比如,加上新的方法,然後,返回修改後的定義。

__new__()方法接收到的參數依次是

  1. 當前準備創建的類的對象;

  2. 類的名字;

  3. 類繼承的父類集合;

  4. 類的方法集合。

什麽時候需要metaclass?

直接在MyList定義中寫上add()方法是更簡單。正常情況下,我們用不上metaclass。但是,總會遇到需要通過metaclass修改類定義的。ORM就是一個典型的例子。

ORM全稱“Object Relational Mapping”,即對象-關系映射,就是把關系數據庫的一行映射為一個對象,也就是一個類對應一個表,這樣,寫代碼更簡單,不用直接操作SQL語句。


Python學習筆記__7.6章 使用原類