回顧面向?qū)ο缶幊?/p>
讓我們先用 30 秒鐘來回顧一下 OOP 到底是什么。在面向?qū)ο缶幊陶Z言中,可以定義 類,它們的用途是將相關(guān)的數(shù)據(jù)和行為捆綁在一起。這些類可以繼承其 父類的部分或全部性質(zhì),但也可以定義自己的屬性(數(shù)據(jù))或方法(行為)。在定義類的過程結(jié)束時,類通常充當用來創(chuàng)建 實例(有時也簡單地稱為 對象)的模板。同一個類的不同實例通常有不同的數(shù)據(jù),但“外表”都是一樣 — 例如, Employee 對象 bob 和 jane 都有 .salary 和 .room_number ,但兩者的房間和薪水都各不相同。
一些 OOP 語言(包括 Python)允許對象是 自省的(也稱為 反射)。即,自省對象能夠描述自己:實例屬于哪個類?類有哪些祖先?對象可以用哪些方法和屬性?自省讓處理對象的函數(shù)或方法根據(jù)傳遞給函數(shù)或方法的對象類型來做決定。即使沒有自省,函數(shù)也常常根據(jù)實例數(shù)據(jù)進行劃分,例如,到 jane.room_number 的路線不同于到 bob.room_number 的路線,因為它倆在不同的房間。利用自省, 還可以在安全地計算 jane 所獲獎金的同時,跳過對 bob 的計算,例如,因為 jane 有 .profit_share 屬性,或者因為 bob 是子類 Hourly(Employee) 的實例。
元類編程(metaprogramming)的回答
以上概述的基本 OOP 系統(tǒng)功能相當強大。但在上述描述中有一個要素沒有受到重視:在 Python(以及其它語言)中,類本身就是可以被傳遞和自省的對象。正如前面所講到的,既然可以用類作為模板來生成對象,那么用什么 作為模板來生成類呢?答案當然是 元類(metaclass)。
Python 一直都有元類。但元類中所涉及的方法在 Python 2.2 中才得以更好地公開在人們面前。Python V2.2 明確地不再只使用一個特殊的(通常是隱藏的)元類來創(chuàng)建每個類對象。現(xiàn)在程序員可以創(chuàng)建原始元類 type 的子類,甚至可以用各種元類動態(tài)地生成類。當然,僅僅因為 可以在 Python 2.2 中操作元類,這并不能說明您可能想這樣做的原因。
而且,不需要使用定制元類來操作類的生成。一種不太費腦筋的概念是 類工廠:一種普通的函數(shù),它可以 返回在函數(shù)體內(nèi)動態(tài)創(chuàng)建的類。用傳統(tǒng)的 Python 語法,您可以編寫:
清單 1. 老式的 Python 1.5.2 類工廠
Python 1.5.2 (#0, Jun 27 1999, 11:23:01) [...]Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam>>> def class_with_method(func):... class klass: pass... setattr(klass, func.__name__, func)... return klass...>>> def say_foo(self): print 'foo'...>>> Foo = class_with_method(say_foo)>>> foo = Foo()>>> foo.say_foo()foo
工廠函數(shù) class_with_method() 動態(tài)地創(chuàng)建一個類,并返回該類,這個類包含傳遞給該工廠 的方法/函數(shù)。在返回該類之前,在函數(shù)體內(nèi)操作類自身。 new 模塊提供了更簡潔的編碼方式,但其中的選項與 類工廠體內(nèi)定制代碼的選項不同,例如:
新聞熱點
疑難解答
圖片精選