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
Python Special Attributes
by thinker
2 Columns
關鍵字:
Python
coding
$Python$ 像許多 OOL 一樣,提供了大量的 special attributes ,以 customize 物件的行為,例如 operator override ,加、減、乘、除,對映的 attribute 為 __add__ 、 __sub__ 、 __mul__ 、 __div__ 。至從 $Python$ 2.x 引入 New Style Class 之後, new style 和 classic class 在行為上有些不同。 new style 和 classic style 的差異: * A op B 時 (op 是加、減、乘、除 等 operator) * new style 會執行 A.__class__.__mul__ 等 attribute * new style 執行的方式 * A.__class__.__mul__(A, B) * classic style 會執行 A.__mul__ * classic style 執行方式 * A.__mul__(B) * A.__mul__ 可能是 * A.__dict__['__mul__'], 也可能是 * A.__class__.__dict__['__mul__'] 。 * bound method new style 和 classic style 的差異點是 * classic style * 呼叫 special attribute 方式,和一般的 object attribute 的呼叫方式一樣。 * 若 instance object 的 dictionary 裡有定義這個 function ,則直接呼叫。 * 否則,使用 class object 所定義的 method,轉成 bound method,然後呼叫。 * new style * 直接,並且只執行 class object 所定義的 method。 * 以 static method 的方式執行。 == Bound Method == bound method 是指在 class object 定義的 method,透過 instance object 讀取時,會自動轉成 bound method。而透過 class object 讀取是,則稱為 unbound method 。由於 classic style 永遠都是透過 instance object 來存取 attribute ,所以可能是讀取到 instance 本身定義的變數,若 instance 本身沒有定義,則在 class 和 base class 找尋。因此,當 A * B 時, class style 永遠是執行 {{{ A.__mul__(B) }}} 有可能是呼叫到 A 本身定義的 function ,或者是在 class 或 base class 所定義的 bound method 。 == Static Method == 雖然 new style 永遠都是執行 class object 或者 base class object 的 method ,而且將之當成 static method 使用。但是, programmer 並不需要宣告成 static method 。其實,你可以看成 python 永遠呼叫 class object 的 unbound method 。 == __getattribute__ == new style class 可以透過這個 special attribute 改變 instance object 的存取行為,但是系統讀取 class object 的 attribute 時,卻不經過這個 method。例如 A * B 時, $Python$ interpreter 會試著讀取 class object 的 __mul__ 這個 attribute 。讀取 class object 的 attribute ,照一般 attribute 的存取方式,應該透過 metaclass 的 __getattribute__ 來讀取 class object 的 atrribute。但是,系統存取這些特殊 attribute 時,不會透過 metaclass 的 __getattribute__ 。 試在 $Python$ interpreter 裡執行下面的指令: {{{ class a(type): def __getattribute__(self, name): print 'a.__getattribute__', name return None class b(object): __metaclass__ = a def __mul__(self, other): print 'b.__mul__', other return 'b.__mul__' c = b() ---- c * 2 ==> b.__mul__ 2 'b.__mul__' ---- c.any ==> Traceback (most recent call last): File "<stdin>", line 1, in ? AttributeError: 'b' object has no attribute 'any' ---- b.any ==> a.__getattribute__ any }}} 從這裡可以發覺, interpreter 在讀取 instance object 的 class object 的 attribute 時,並不會無限上綱的要求 metaclass 的 __getattribute__ 來 handle 。若是直接讀取 class object 的 attribute ,則會呼叫 metaclass 的 __getattribute__ 。換句話說, $Python$ 只會呼叫上層 class object 的 __getattribute__ 。 == 結語 == $Python$ 2.x 在 data model 上的改變,簡化了系統規則。也移除了一些不合理、不合邏輯的 tricky 。另一方面,也使的語言的彈性大增, meta programming 更成熟。從 $Python$ 1.x 開始學習的人,現在有必要 review 一下新版的改變。
最後更新時間: 2007-01-07 20:26:05 CST |
引用
查詢:
COMMENTS: