robot
最新文章(10)
Mqskit 和其它相關工具
CPython 的 GC 二、三事
寫 Mecurial Extension 是件快樂的事!
Mozilla 台灣辨公室徵人啟事
關於 Apple 的兩項專利
core dump 之前的 frame
怎麼發出 beep 聲?
先承認你要找的是奴才吧!
程式碼要清的多乾淨?
FreeBSD 的 Thread-Local Storage 實作
首頁
新編
最新留言
Entries RSS
重要關鍵字(10)
coding (122)
Python (93)
FreeBSD (71)
WEB (61)
URL (48)
hardware (46)
javascript (36)
Linux (34)
blog (30)
C++ (16)
所有關鍵字
新增 URL
New Style Classes of Python
by thinker
2 Columns
關鍵字:
Python
從 $Python$ 2.2.x 之後,引進了 new style class,以漸進式的方式,消除過去 built-in type 和 user-defined classes 之間的差異。最大的差異是 Guido van Rossum 在 linkname:[Unifying types and classes in $Python$ 2.2] http://www.python.org/download/releases/2.2.3/descrintro/#introduction 寫道: ```Perhaps the most obvious one is the restriction against using built-in types (such as the type of lists and dictionaries) as a base class in a class statement. ''' 這些差異暫且不論,我們著眼在新的設計, New Style Class。 == 新設計 == 在新的設計中,每一種 data type,甚至是 built-in 的 int、list、dictionary...... 等,都可以當作 user-defined class 的 base class。然而,這不是重點,我們想知道是怎麼做的。 在新設計中,class 多了一個 special method: __new__。當呼叫 class 以建立一個 intance 時,$Python$ 首先呼叫 class 的 __new__ method,然後才呼叫 __init__。__new__ 的作用是傳回 class 的 instance,再由 __init__ 初始化。 $Python$ 透過多種途徑產生 object,大部份都會尊循前面所提的過程,先呼叫 __new__ 然後呼叫 __init__,但有時侯 __init__ 並不會被呼叫。例如透過 pickle 將 object load 進記憶體。但 __new__ 是一定會被執行的。 == Immutable Built-in Type == immutable built-in type 是指 int、float、string...... 這類的 type,一旦建立之後,就無法改變。當我們投定一個 int 變數的值時,其實是指定另一個 int object 給變數。像這種 immutable type,就無法在 __init__ 裡,去改變其內容,因為這時物件已建立了,無法改變。 __new__ 是在 instance 建立之前呼叫,目的是傳回一個新的 instance。因此,我們可以透過修改傳遞給 base class 的參數,達到 customize 的目的。我們以 inch 為例,自動將英寸轉成公分: {{{ class inch(float): def __new__(cls, arg=0.0): return float.__new__(cls, arg * 2.54) >>> print inch(1.0) 2.54 >>> }}} 如此就可以在一開始就指定不同的值,而非事後修改。 __new__ 提供機會,在 instance 建立之前,改變建立 isntance 的流程。 == __metaclass__ == __new__ 提供改變建立 instance 流程的機會,而 metaclass 則提供改變建立 class 流程的機會。New style class 的每一個 class 都是一個物件,也有自己的 class,也就是 class 的 class,稱為 metaclass。 metaclass 可透過 class 的 __metaclass__ 這個 class 變數指定,當 $Python$ run 到定義 class 的指令時,將建立一個 dictionary,包含 class 所定義的所有變數和函數。如果 class 或 base classes 是定義 __metaclass__,且 __metaclass__ 為 class M,則 $Python$ 執行: {{{ cls = M.__new__(M, name, bases, dict) assert cls.__class__ is M M.__init__(cls, name, bases, dict) }}} 類似這樣的指令。其中 cls 是和新 class 同名的變數符號,而 name 是 class 名稱字串,bases 是所有的 base classes,dict 就是前面提到的 dictionary。這些動作其實就是為 M 建立一個新的 instance,只是這個 instance 剛好也是一個 class。 == 使用 metaclass == metaclass 有什麼用呢?幫你快速建立某一類的 class。例如:我們可以設計一個 remote object proxy 的 metaclass。 {{{ class remote_obj: def __init__(cls, name, base, dict): super(remote_obj, cls).__init__(cls, name, base, dict) for name in dict: setattr(cls, name, create_stub(name, dict)) class a: __metaclass__ = remote_obj def foo(self): pass def bar(self, a): pass }}} 那麼,任何呼叫 a.foo() 和 a.bar() 都會經過 stub 傳送到遠端。 如果有多於一個以上的 base class 有定義 __metaclass__,那要用哪一個?這個問題請參考 Guido 的文章 :p == 結論 == New style class 除了提供 built-in type 和 user-defined class 的一致性,也增加更多彈性,讓 meta programming 更易實現。作為 $Python$ 的 programmer,你可以不用理會這些新功能,但了解並學習這些新功能,將開啟你更大的想象空間。
最後更新時間: 2006-10-04 19:49:33 CST |
引用
查詢:
COMMENTS: