1、概覽
動態語言和靜態語言最大的不同,就是函式和類的定義,不是編譯時定義的,而是執行時動態建立的。
1.1、
type()
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個引數:
class的名稱;
繼承的父類集合,注意python支援多重繼承,
如果只有乙個父類,別忘了tuple的單元素寫法
;class的方法名稱與函式繫結,這裡我們把函式fn繫結到方法名hello上。
1.2、metaclass
除了使用
type()
動態建立類以外,要控制類的建立行為,還可以使用metaclass。
先定義metaclass,就可以建立類,最後可以建立例項
用metaclass給自定義的mylist類增加乙個add方法:
# metaclass是類的模板,所以必須從`type`型別派生:
class listmetaclass(type):
# metaclass的類名總是以metaclass結尾,以便清楚地表示這是乙個metaclass
def __new__(cls, name, bases, attrs):
# 為類建立了乙個
add方法
return type.__new__(cls, name, bases, attrs)
class mylist(list, metaclass=listmetaclass):
# 指示使用listmetaclass來定製類,傳入關鍵字引數metaclass
pass
當我們傳入關鍵字引數metaclass時,魔術就生效了,它指示python直譯器在建立mylist時,要通過listmetaclass.__new__()來建立,在此,我們可以修改類的定義,比如,加上新的方法,然後,返回修改後的定義。
__new__()方法接收到的引數依次是:
當前準備建立的類的物件;
類的名字;
類繼承的父類集合;
類的方法集合。
什麼時候需要metaclass?
直接在mylist定義中寫上add()方法是更簡單。正常情況下,我們用不上metaclass。但是,總會遇到需要通過metaclass修改類定義的。orm就是乙個典型的例子。
Python學習筆記 7 5章 使用列舉類
1 概覽 當我們需要定義有規律的常量時,比如月份。我們可以用 enum 類來實現這個功能 1.1 直接使用enum類 from enum import enum month enum month jan feb mar apr may jun jul aug sep oct nov dec type...
Python學習筆記 12 10章 XML
1 概覽 xml雖然比json複雜,在web中應用也不如以前多了,不過仍有很多地方在用,所以,有必要了解如何操作xml。1 dom vs sax 操作xml有兩種方法 dom和sax。dom會把整個xml讀入記憶體,解析為樹,因此占用記憶體大,解析慢,優點是可以任意遍歷樹的節點。sax是流模式,邊讀...
Python學習筆記 20 2章 asyncio
1 概覽 asyncio 是python 3.4 版本引入的標準庫,直接內建了對非同步 io的支援 asyncio 的程式設計模型就是乙個訊息迴圈。我們從 asyncio 模組中直接獲取乙個 eventloop 的引用,然後把需要執行的協程扔到 eventloop 中執行,就實現了非同步io。1.1...