2008年12月3日

[讀書筆記] Python 核心編程 (Ch13~14)

第 13 章物件導向程式設計 / 第 14 章執行環境 ( 講如何調用 & 終止程序 )

本書的 Part I: Core Python 就到此為止了;接下來的 Chapter 15 ~ 23 被歸為 Part II: Advanced Topics,不一定會繼續寫筆記 =3=

Chapter 13: Object-Oriented Programming

  • types 和 classes 被統一了。
  • object 是 mother of all classes。宣告時至少繼承自 object 的為 new-style class,否則為 classic class。
  • class 的宣告與定義沒有區別。
  • 對 instance 做 assignment 會增加 reference count
  • class method 定義時需要的 self 參數,同 C++ 的 this,是為了識別呼叫的 instance。
  • __init__() 為 constructor,應回傳 None。__del__() 為通常無需去碰它的 destructor
  • 子類重寫 __init__() 後就不會自動調用父類的了。需顯式調用 parent.__init__(self,...) 並顯式傳遞 self 參數 ( 因為不是透過 instance 調用,interpreter 無法自動給出 method 所需的 self )。__del__() 亦同。
  • 基本上,class attribute 都是 public
  • class 定義中出現的 variable assignment 產生 class attribute (static variable)
  • 可為個別 instance 添加 attribute,尤以 __init__() 中設定 self.attribute 最為常見。
  • 同名時會優先存取 instance attribute,然後才是 class attribute
  • dir(obj) 傳回 list,列出 obj 的所有 attribute 及 method。help(obj) 也可列出這些資料。
  • 特殊的 class attribute:__name__ class name string、__doc__ documentation string、__bases__ 列出 tuple of direct parents、__dict__ 屬性的 {name:value}、__module__ 定義所在處。instance attribute:__class__ type,避免顯式給出名稱。
  • documentation string 不會被繼承。
  • 繼承時以 DFS 搜尋 indirect base classes 的集合。
  • 管理 instance count 的好方法是用 static member
  • binding:bound method 需有 class instance 才能被呼叫。想呼叫 unbound method 必需言明 class name 並手動傳入 self
  • class 中定義的 function 若不帶 self 參數,即為 static method 或 class method。用 @staticmethod 修飾為 static method;用 @classmethod 並傳入標示 class 的變數 ( 通常為 cls ),為 class method。
  • 可由多個 parent classes 繼承 attribute 和 method
  • 若 C 繼承 P,super(C, self).foo() 等同於 P.foo(self),可避免顯式給出 parent name
  • 繼承後,__init__() 若沒被覆寫就會自動調用 parent class 的;覆寫後則不會。
  • 想從 built-in immutable type 繼承時,constructor 用 class method __new__(cls,...)
  • Table 13.4 列出一大票可供自訂的 special methods
  • 多重繼承時的 method resolution order:由左至右 BFS。class attribute __mro__ 給出這個次序。
  • BIFs:issubclass(sub, sup)、isinstance(inst, cls)、has/get/set/delattr(inst, string)、dir()、super()、vars()
  • 可在定義時用 __repr__ = __str__ 這樣設定 reference alias
  • 相較於 addition operation 傳回新的物件,像 += 這樣的 in-place operation 需傳回 self。
  • attribute 加前綴 _ 可防止 from module import * 這樣導入屬性。前綴 __ 可防止繼承階層中的名稱衝突。
  • Delegation:增刪修改原有物件的功能。藉由覆寫 __getattr()__ 實現。
  • Section 13.16: Advanced Features of New-Style Classes。嗯,真的很 advanced。
  • class attribute __slots__ 限制了 instances 能存取的屬性,主要目的是節約記憶體。
  • Descriptors 有 3 個 special method 做為 descriptor protocol:__get__()、__set__()、__delete__()。激晦澀,讀不通...... =3=
  • 還有啥 metaclass 的,一樣難懂......

Chapter 14: Execution Environment

  • BIFUDFBIM 都有許多內建的 attribute。
  • 定義 class 時若實作了 __call__(),就可以對 instance 做 () 呼叫。
  • compile(str, file, type) 將 str 以 type 類型編譯。編譯後的 object 可用 exec 或 eval() 跑。先 compile 可避免重覆解讀字串。
  • exec obj、eval(obj) 以 Python interpreter 的角度對待 obj。另有 execfile(filename)
  • input(str) 等價於 eval(raw_input(str))
  • Section 14.5 講述 os module 中一大票用來跑程序的函式。
  • sys.exit(status=0) 丟出 SystemExit 這個 ( 唯一不被當成錯誤的 ) 異常,表明退出 python 的意願。

7 則留言:

  1. some interesting feature

    in multiple inheritance

    super(C, self)..__init__() != P.__init__(self),

    my code is in
    http://gist.github.com/79765
    http://gist.github.com/79767

    for multiple inheritance, it is bad idea for reference counting in the Top class,

    I suspect super(C, self).foo() has different behavior as P.foo(self) as well.

    回覆刪除
  2. 真的耶@@
    沒考慮到多重繼承的狀況...

    感謝分享

    回覆刪除
  3. There is a great post http://hi.baidu.com/isno/blog/item/32899358e2a6a4d99d820419.html

    and most credits must goes to the author.

    I m still confused, so I try to test it on my own.

    And I m not sure if all his conclusion is right,

    Let's wait and see.

    回覆刪除
  4. 真強大...
    不過個人傾向不再深究底層細節了 = =a
    以後遇到這樣的狀況,我會回憶起來然後想辦法迴避吧
    Just one of the hundreds of tools.

    回覆刪除
  5. your python study notes are nice, well done, keep going

    回覆刪除
  6. 看了這幾篇,勝過讀三個月的書呀。

    回覆刪除