python核心編程--筆記

1.1 –d   提供調試輸出 html

1.2 –O   生成優化的字節碼(生成.pyo文件) java

1.3 –S   不導入site模塊以在啓動時查找python路徑 python

1.4 –v   冗餘輸出(導入語句詳細追蹤) react

1.5 –m mod 將一個模塊以腳本形式運行 linux

1.6 –Q opt 除法選項(參閱文檔) c++

1.7 –c cmd 運行以命令行字符串心事提交的python腳本 git

1.8 file   以給定的文件運行python腳本 程序員

2 _在解釋器中表示最後一個表達式的值. 正則表達式

3 print支持類c的printf格式化輸出: print 「%s is number %d!」 % (「python」, 1) 算法

4 print的輸入內容後面加逗號, 就會使其輸入不換行

5 把輸出重定向到日誌文件:

logfile = open(「c:/1.log」, 「a」);   //打開文件c:/1.log使用a模式..即add, 添加.

print >> logfile, 「Fatal error: invalid input!」;   >>爲重定向..將print的結果重定向到logfile, 輸出內容是」Fatal error: invalid input!」…

logfile.close();  //關閉文件流…

6 程序輸入: raw_input(「提示字符串」): user = raw_input(「請輸入您的姓名」);

7 int(數值)…..將數值字符串轉換成整數值…

8 運算符:

8.1 + - * / %是和其餘語言相同的加減乘及取模運算.取餘運算

8.2 / 在浮點取模中獲得的結果是完整的浮點數

8.3 // 在浮點取模中獲得的結果是通過捨去運算的結果.

8.4 ** 是乘方

8.5 >>和<<的移位運算也支持. 但不支持java中的>>> 和<<< 移位.

8.6 < <= > >= ++ != <> 等比較運算符

8.7 and or not 等邏輯運算符

9 變量和賦值: python是弱類型語言..

10 list, tuple, map * 4 獲得的結果是一個新的 list | tuple | map, 是原數據的4份

11 數字:

11.1 int(有符號整數)

11.2 long(長整數)

11.3 bool(布爾值)

11.4 float(浮點值)

11.5 complex(複數)

11.6 python2.3開始, 若是結果從int溢出, 會自動轉型爲long

11.7 python2.4開始支持decimal數字類型, 須要導入decimal模塊..因爲在二進制表示中會有一個無限循環片斷, 普通的浮點1.1實際是不能被精確表示的, 被表示爲1.1000000000000001. 使用print decimal.Decimal(‘1.1’);則能夠獲得精確的1.1

12 字符串:  引號之間的字符集合, 支持使用成對的單引號和雙引號, 三引號(三個連續單引號或雙引號)能夠用來包含特殊字符.  使用索引運算符[]和切片運算符[ : ]能夠獲得子字符串…字符串中第一個字符的索引是0, 最後一個字符的索引是-1;

13 列表和元組: 能夠看做是普通的數組, 能保存任意數量任意類型的python對象…

13.1 列表元素用中括號包裹, 元素的個數及元素的值能夠改變.

13.2 元組元素用小括號包裹, 不能夠更改, 儘管他們的內容能夠, 元組能夠當作是隻讀的列表.  能夠使用切片運算獲得子集.

14 字典: 至關於其餘語言中的map, 使用{key: value}的方式表示. 取值的方式和其餘語言的map一致.  也能夠直接使用map[key] = value的方式爲其賦值.

15 條件語句:

if expression:

         path 1

elif expression2:

         path2

else:

         path3

16 while循環

while expression:

         process business

17 for循環

for item in list|tuple|map:

         print item

17.1 range(len(list))獲得一個list長度範圍內的整數list, 方便遍歷過程當中獲取索引值.

17.2 python2.3中增長了enumerate(), 能夠經過它遍歷list, 同時獲得索引和值

for index, data in enumerate(list):

         print index, 「:」, data,

17.3 列表解析: sqdEvens = [x ** 2 for x in range(8) if not x % 2], 獲取一個序列, 該序列是0-8的數字中全部x%2爲0(false)的x的平方

18 文件和內建函數: open(), file()

18.1 handle = open(file_name, access_mode = 「r」), 只讀方式打開文件, 獲得的句柄是handle..該方法若是沒有提供access_mode, 默認是r

19 異常處理: raise能夠故意引起異常

try:

         # process

except IOError, e:

         # error process

20 函數: 若是函數中沒有return語句, 自動返回None對象

def function_name([arguments]):

         「optional document string」

         function_suite

20.1 python的函數調用中參數是引用傳遞

20.2 能夠在定義函數的時候, 在參數列表中經過=設置參數的默認值.

21 類:

21.1 定義:

class class_name:

         static_variable_name = value

         def __init__(self, [arguments]):

                   //operation

                   //self in here is the reference for this class instance

         def general_method_name(self, [arguments]):

                   //operation

                   //self is the class instance

                   //if you want to use class variable, please use like self.__class__.__name__

21.2 實例化: instance = class_name([arguments, …]);

22 模塊: 不帶.py後綴名的文件名…一個模塊建立以後, 能夠使用import導入這個模塊使用.

22.1 訪問模塊內的函數或變量: module_name.function() | module_name.variable | module_name.class_name

22.2 sys模塊概覽

22.2.1 sys.stdout.write(‘Hello World!\n’)  //使用sys模塊的標準輸出

22.2.2 sys.platform  //返回系統的標記

22.2.3 sys.version  //返回系統的版本

23 PEP: 一個PEP就是一個python加強提案(python enhancement proposal), 是在新版python中增長新特性的方式…索引網址是: http://python.org/dev/peps

24 一些經常使用函數

24.1 dir([obj])  顯示對象的屬性, 若是沒有提供參數, 顯示全局變量的名字

24.2 help([obj])  顯示對象的文檔, 若是沒有參數, 進入交互式幫助

24.3 int(obj)  將一個對象轉換爲整數

24.4 len(obj)  返回對象的長度

24.5 open(file_name, mode)  以mode(r|w|a…)方式打開一個文件

24.6 range([[start, ]stop[, step]])  返回一個整數列表…結束值是stop-1, step默認是1

24.7 raw_input(str)  提示str等待用戶輸入

24.8 str(obj)  將一個對象轉換爲字符串

24.9 type(obj)  返回對象的類型…返回值自己是一個type對象

24.10 sum(iterable[, start=0])  能夠對純數值的list|tuple|map進行求和操做..

24.11 dir([object])  若是沒有參數得到當前腳本scope內定義的對象, 若是有參數, 返回該對象內部定義的對象, 若是該對象有一個__dir__方法, 該方法將被調用, 而且必須返回屬性的列表…這就容許經過自定義__getattr__()或__getattribute__()方法的方式實現dir的自定義顯示屬性列 表….若是沒有指定參數, 是根據該對象的__dict__內存字典的最佳聚合信息顯示的..

24.12 type([object])  參數爲空顯示<type ‘type’>, 參數不爲空顯示該對象的類型

24.13 type(name, bases, dict)  經過名稱, 基類, 內存字典動態建立一個類型

24.14 object__name.__doc__  查看該對象的文檔字符串

24.15 __doc__ 對象的文檔字符串, 該文檔字符串在定義對象時寫在對象語句塊中第一句, 使用單純的字符串的方式表示

24.16 sys.exit()  退出python解釋器

24.17 append(Object)  給list添加一個元素

24.18 os.linesep 返回的是系統換行符…不一樣的系統換行符是不一樣的, 使用linesep能夠提升代碼跨平臺性

24.19 string_variable_name.strip([chars])  脫離, 濾去字符串中的某些字符, 若是沒有參數返回原字符串

25 數值按進制分爲:

25.1 二進制: 0b101010

25.2 八進制: 07167

25.3 十進制: 98767

25.4 十六進制: 0xf2134

Python基礎(chapter3)

1 setence and syntax語句和語法

1.1 #爲註釋符號

1.2 \n是標準行分隔符, 一般一個語句一行

1.3 反斜線\表示下一行繼續, 用來將單條語句放入多行…儘可能使用括號代替

1.4 分號;表示將兩個語句鏈接在一行中…不提倡

1.5 冒號:表示將代碼塊的頭和體分開

1.6 語句(代碼塊)用縮進塊方式體現: 同一個代碼組的代碼必須嚴格左對齊..因爲不一樣的editor製表符寬度不一, 爲了使代碼跨平臺, 推薦使用4個空格縮進

1.7 不一樣縮進深度分隔不一樣的代碼塊

1.8 python文件以模塊的形式組織: 模塊以磁盤文件的形式存在, 不該該讓某個模塊充斥的太大

2 賦值

2.1 賦值語句沒有返回值, 但能夠使用鏈式賦值

2.2 python2.0開始支持增量賦值(算符和等號鏈接賦值), 可是python不支持++, --

2.3 賦值操做中, 可變對象會被直接修改(引用位置值的修改), 不可變對象則被從新賦予新的對象(引用修改)

2.4 多元賦值: a, b, c = 1, 2, ‘string’, 建議使用tuple的方式進行多元賦值: (a, b, c) = (1, 2, ‘string’)

3 swap操做: x, y = y, x

4 標識符

4.1 大小寫敏感

4.2 python的關鍵字列表和iskeyword()函數在keyword模塊, 方便查閱

4.3 內建: built-in能夠看做是系統保留字….對於一些內建函數須要覆蓋(重定義, 替換)…built-in是__builtins__模塊的成員, 該模塊由解釋器自動導入

4.4 python不支持重載

4.5 下劃線: 做爲變量前綴和後綴指定特殊變量

4.5.1 _xxx: 不用’from module import*’導入

4.5.2 __xxx__: 系統定義名字

4.5.3 _xxx: 類中的私有變量名

5 python之禪

The Zen of Python, by Tim Peters

python之禪. 做者Tim Peters

 

Beautiful is better than ugly.

漂亮勝於醜陋

Explicit is better than implicit.

詳盡勝於含蓄

Simple is better than complex.

簡單勝於複雜

Complex is better than complicated.

組合勝於複雜(結構)

Flat is better than nested.

單一勝於嵌套

Sparse is better than dense.

稀少勝於繁雜

Readability counts.

可讀性價值

Special cases aren't special enough to break the rules.

特例不足以違反規則

Although practicality beats purity.

實踐勝於理論

Errors should never pass silently.

錯誤可能從不沉默

Unless explicitly silenced.

除非明白沉默

In the face of ambiguity, refuse the temptation to guess.

面對歧義, 不被猜測誘惑

There should be one-- and preferably only one --obvious way to do it.

可能僅有一種更好的方法

Although that way may not be obvious at first unless you're Dutch.

 

Now is better than never.

如今勝於一切

Although never is often better than *right* now.

 

If the implementation is hard to explain, it's a bad idea.

難於解釋的實現是很差的

If the implementation is easy to explain, it may be a good idea.

易於明白的實現多是個好方案

Namespaces are one honking great idea -- let's do more of those!

名空間是一個好方案, 讓咱們去超越這些

6 模塊組織

# 起始行

# 模塊文檔

# 模塊導入

# 變量定義

# 類定義

# 函數定義

# 主程序

7 __name__用於指示模塊應該如何被加載, 若是值是」__main__」說明是主模塊, 若是是模塊名, 說明是被導入的

8 主模塊測試代碼

def main():

         # business process

if(__name__ == ‘__main__’)

         main()

9 內存管理

9.1 基本

9.1.1 弱類型 – 動態類型

9.1.2 programmer不關心內存管理

9.1.3 變量並會被回收

9.1.4 del語句可以直接釋放資源

9.2 變量未初始化不容許使用

9.3 引用計數: 對於一個內存堆中的對象, 有多少個指針引用它..引用計數就是多少, 引用計數爲0時, 該對象能夠被垃圾回收器回收

9.3.1 增長

9.3.1.1 對象建立

9.3.1.2 別名建立(引用賦值)

9.3.1.3 參數傳遞(引用傳值)

9.3.1.4 被容器引用

9.3.2 減小

9.3.2.1 引用生命週期結束

9.3.2.2 對象別名被顯示銷燬 del y

9.3.2.3 對象別名被賦予其餘引用

9.3.2.4 窗口對象自己被銷燬

9.3.3 del

9.3.3.1 從如今的名字空間中刪除一個別名

9.3.3.2 對象的引用計數減一

9.4 垃圾回收: 有對象引用計數爲0, 對象被顯示告知須要銷燬, 有內存消耗大戶存在致使系統壓力較大時, 垃圾回收機制運行, 清理須要回收的內存區域…垃圾回收機制還有一個循環垃圾回收器, 確保釋放循環引用對象(a引用b, b引用a, 致使其引用計數永遠不爲0)

10 將引入的其餘模塊中經常使用的變量從新賦予一個本地別名(ls = os.linesep)不只能夠避免冗長的變量名, 又能夠提升加載速度(由於如今是本地變量了)

11 重要的其餘模塊

11.1 debugger: pdb容許設置斷點, 逐行調試, 檢查堆棧, 還支持過後調試

11.2 logger: logging分緊急, 錯誤, 警告, 信息, 調試五級日誌

11.3 profilers: 性能測試器

11.3.1 profile: python編寫, 測試函數執行時間, 每次腳本執行總時間.

11.3.2 hotshot: python2.2, c編寫, 解決了性能測試過載問題, 但須要更多時間生成結果, python2.5修正了hotshot的時間計量bug

11.3.3 cProfile: python2.5, c編寫, 須要較長時間從日誌文件載入分析結果, 不支持子函數狀態細節, 某些結果不許

python對象(chapter4)

1 python對象有三個特徵: 身份和類型是隻讀的, 若是對象支持不支持更新操做, 那麼值也就是隻讀的.

1.1 身份: 惟一的身份標識, 能夠使用內建函數id()獲得, 能夠看做是對象的內存地址…

1.2 類型: 對象的類型決定該對象保存什麼類型的值, 能夠進行什麼操做, 遵循什麼規則., 能夠使用內建函數type()查看python對象的類型.

1.3 值: 對象表示的數據項

2 對象屬性: 主要有屬性, 值, 相關聯的可執行代碼(method), 一些python類型也有數據屬性, 含有數據屬性的對象包括但不限於: 類, 類實例, 模塊, 複數, 文件.

3 基礎數據類型: 數字, 整形, 布爾型, 長整型, 浮點型, 複數型, 字符串, 列表, 元組, 字典.

4 其餘內建類型: 類型, None, 文件, 集合/固定集合, 函數/方法, 模塊, 類

4.1 type(type(1)) 能夠看出類型對象自己也是對象, 它的類型是type

4.2 None的類型是NoneType, NoneType只有一個值, 就是None, 不支持任何運算也沒有任何內建方法, 布爾值總返回False

5 每一個對象天生都有布爾值, 如下對象的布爾值是False

5.1 None

5.2 False(bool類型)

5.3 全部值爲0的數

5.4 ‘’ 空字符串

5.5 [] | () | {} 空列表, 空元組, 空字典

5.6 用戶建立的實例若是定義了nonzero(__nonzero__())或length(__len__())且值爲0, 那麼返回的布爾值也是False

6 當要獲取一個對象的布爾值的時候, 首先會調用__nonzero__(必須返回布爾類型或者int類型.)方法, 若是實現了該方法, 就返回該方法返回的布爾值, 若是沒有實現該方法, 繼續調用__len__方法(該方法返回值必須是大於等於0的), 若是實現了__len__方法, 就根據其返回值返回布爾值. 

7 內部類型: python內部機制

7.1 代碼: 編譯過的python的源代碼片斷, 是可執行對象. 經過調用內建函數compile()能夠獲得代碼對象. 代碼對象能夠被exec命令或eval()內建函數來執行.   代碼是用戶自定義函數的核心, 運行期得到上下文..  __code__是函數的一個屬性, 函數除了代碼這個屬性, 還有函數名, 文檔字符串, 默認參數, 全局命名空間等必須的屬性

7.2 幀對象: 用於跟蹤記錄對象

7.3 跟蹤記錄: 用於異常發生時, 程序訪問跟蹤記錄對象處理程序.

7.4 切片:

7.4.1 步進切片sequence[::number] number爲負數, 倒序顯示字符串, 正數則正序顯示字符串, 數值表明顯示字符的step值.  

7.4.2  多維切片 sequence[start1: end1, start2: end2]

7.4.3  省略切片 sequence[…, start1: end1]

7.4.4 切片對象 使用slice([start, ]stop[, step])能夠建立一個切片對象

7.5 省略對象: 用於擴展切片語法, 起記號做用..在切片語法中表示省略號, 省略對象有一個惟一的名字Ellipsis, 布爾值始終是True

7.6 Xrange: 調用xrange()生成Xrange對象, 相似內建函數range, 用於節省內存使用或range沒法完成的超大數據集場合

8 標準類型運算符

8.1 對象值比較

8.1.1 數字根據大小比較

8.1.2 字符串根據字符前後順序比較

8.1.3 list | tuple | dict順序按照其中元素(dict按照鍵)比較

8.1.4 鏈式比較至關於多個比較使用and鏈接

8.1.5 自定義類型對象的比較是引用值比較, 也就是id(object_name)的比較

8.2 對象身份比較

8.2.1 is / is not用來比較兩個別名是否引用同一個對象

8.2.2 整數對象和字符串對象是不可變對象…

8.3 布爾類型運算符: and, or, not

9 標準類型內建函數

9.1 cmp(obj1, obj2)  比較obj1和obj2, 根據比較結果返回整數i, i<0 à obj1<obj2, i>0 à obj1>obj2, i==0 à obj1 == obj2….自定義類型中經過定義方法__cmp__(target)來實現….使用比較運算符, 或直接調用cmp時該方法被調用

9.2 type(obj)  獲得一個對象的類型, 返回相應的type對象

9.3 str(obj)  返回對象適合可讀性好的字符串表示…在自定義類中使用__str__(self)返回一個字符串, 調用str(obj)時會被隱式調用

9.4 repr(obj)  返回一個對象的字符串表示, repr返回的字符串一般能夠被用於使用eval動態建立一個對象.  一般 obj == eval(repr(obj))是成立的

9.5 ``, 反單引號, `obj`和repr(obj)作的事情是同樣的.

9.6 isinstance(obj, (type[, type, …]))  判斷obj是否是第二個參數tuple中的列舉的類型的實例

9.7 types模塊提供一些已知的類型

9.8 因爲每一種類型都只有一個類型對象, 因此, 能夠使用引用比較代替值比較以提高性能: 用if type(num) is types.IntType 替代if type(num) == types.IntType

9.9 from-import: 只引入某個模塊的一部分屬性: 好比from types import IntType 這樣作能夠有效的減小查詢次數

9.10 python的operator模塊中有絕大多數運算符對應的同功能的函數可供使用.

10 類型工廠函數: int(), long(), float(), complex(), str(), Unicode(), basestring(), list(), tuple(), type(), dict(), bool(), set(), frozenset(), object(), classmethod(), staticmethod(), super(), property(), file()

11 標準類型的分類:

11.1 標準類型是」基本內建數據對象原始類型」

11.1.1 基本: 是python的標準或核心

11.1.2 內建: python默認提供

11.1.3 數據: 用於通常數據存儲

11.1.4 對象: 對象是數據和功能的默認抽象

11.1.5 原始: 這些類型提供的是最底層的粒度數據存儲

11.1.6 類型: 自己就是數據類型

11.2 按存儲模型進行分類:

11.2.1 標量/原子類型: 數值, 字符串等能夠存儲單一字面對象的類型.

11.2.2 容器類型: 列表, 元素, 字典等能夠存儲多個字面變量的類型, python中的容器類型均可以存儲不一樣類型的元素

11.3 按更新模型進行分類:  對象建立以後, 值不能夠改變, 注意: 這裏是對象, 而不是變量

11.3.1 可變類型: 列表, 字典

11.3.2 不可變類型: 數字, 字符串, 元組

11.4 按訪問模型進行分類: 訪問對象的方式

11.4.1 直接訪問: 數值

11.4.2 順序訪問: 列表, 元組, 字符串等能夠按照索引訪問的類型

11.4.3 映射訪問: 字典

12 不支持的類型: char, byte, pointer

數字(chapter5)

1 支持的數字類型: 整型, 長整型, 布爾型, 雙精度浮點型, 十進制浮點型和複數

2 整型

2.1 布爾型  包含True和False兩個值的整型

2.2 標準整數類型  0x表示十六進制, 無前綴表示十進制, 0表示八進制, 0b表示二進制

2.3 長整型  整數後加L, 表示範圍與可用內存大小有關..

3 雙精度浮點數: 一個符號位, 52個底位, 11個指數位. 使用後綴e表示指數

4 複數: 實數 + 序數J構成一個複數

4.1 python中的複數概念

4.1.1 虛數不能單獨存在, 老是和一個值爲0.0的實數部分一塊兒構成一個複數

4.1.2 複數由實數部分和虛數部分組成

4.1.3 表示虛數的語法: real + imagJ

4.1.4 實數部分和虛數部分都是浮點數

4.1.5 虛數部分必須有後綴j或J

4.2 複數的內建屬性

4.2.1 real 複數的實部

4.2.2 imag 複數的虛部

4.2.3 conjugate() 返回該複數的共軛複數

5 強制類型轉換規則

 

6 python提供python解釋器的啓動參數Qdivision_style, -Qnew執行新的除法行爲, -Qold執行傳統除法行爲, 默認是-Qold…-Qwarn和-Qwarnall能夠用來度過過渡期

7 冪運算符** 比左側單目運算符優先級高, 比右側單目運算符優先級高

8 位運算符: ~, &, |, ^, <<, >>

8.1 負數會被當成正數的二進制補碼處理

8.2 左移和右移N位等同與無溢出檢查的2的N次冪運算

8.3 長整數的位運算使用一種通過修改的二進制補碼形式, 使的符號位能夠無限左移

8.4 ~是單目運算符

9 內建函數和工廠函數

9.1 數字類型函數:

9.1.1 轉換工廠函數: int(), long(), float(), complex(), 接受參數第一個是要轉換的值, 第二個是進制..若是要轉換的值是string才能使用第二個函數指定進制. 

9.1.1.1 python2.2開始, 加入了bool(), 用來將整數1和0轉換成爲標準布爾值(全部非0數都返回True). 

9.1.1.2 python2.3的標準數據類型添加了Boolean類型, true和false也有了常量值True和False, 而再也不是1和0

9.1.1.3 bool(obj) 返回obj對象的布爾值, 也就是obj.__nonzero__()

9.1.1.4 complex(real, imag=0.0)

9.1.2 功能函數

9.1.2.1 abs(number) 返回數字的絕對值, 若是是複數, 返回math.sqrt(num.real2 + num.imag2)

9.1.2.2 coerce(number1, number2): 返回按照類型轉換規則轉換獲得的兩個數字組成的元組

9.1.2.3 divmod(number1, number2)  返回一個包含商和餘數的元組, 整數返回地板除和取餘操做結果, 浮點數返回的商部分是math.floor(number1/number2), 複數的商部分是ath.floor((number1/number2).real)

9.1.2.4 pow()和**功能相同

9.1.2.5 round(number[, base]) 對浮點數進行四捨五入運算, base參數是小數位參數, 若是不指定, 返回與第一個參數最接近的整數的浮點形式

9.1.2.6 int() 直接去掉小數部分, floor()獲得最接近但小於原數的整數, round()獲得最接近原數的整數

9.1.3 整數的內建函數: hex(), oct(), bin()…ord(「A」) 接受一個ascii或unicode字符, 返回相應的unicode值 çè  char(65L)接受unicode碼值, 返回對應的unicode字符.

10 其餘數字類型

10.1 布爾數:

10.1.1 布爾型是整型的子類, 可是不能再被繼承而生成它的子類.

10.1.2 沒有__nonzero__()方法的對象默認值是True

10.1.3 對於值爲0的任何數字或空集(空的list|tuple|dict)在python中值都是False

10.1.4 數學運算中, True ==1, False == 0

10.2 十進制浮點數: from decimal import Decimal

11 數字科學計算的包

11.1 高級的Third package: Numeric(NumPy)

11.2 python自帶的數字類型相關模塊

11.2.1 decimal  十進制浮點運算類Decimal

11.2.2 array  高效數值數組(字符, 整數, 浮點數)

11.2.3 match/cmatch  標準c庫數學運算函數. 常規數學運算在match, 複數運算在cmatch

11.2.4 operator  數字運算符的函數實現

11.2.5 random  僞隨機數生成器

11.2.5.1 randint(start, end)隨機生成start, end之間的一個整數

11.2.5.2 uniform(start, end)隨機生成範圍內的一個浮點數

11.2.5.3 randrange([start ,]stop[, step])隨機生成start, stop內按step步增數字範圍的一個整數

11.2.5.4 choice(sequence)隨機返回給定的序列中的一個元素

序列: 字符串, 列表和元組(chapter6)

1 對全部序列類型都適用的操做符(優先級從高到低, 不適用於複合類型的對象比較)

1.1 成員關係操做符: int, not in

1.2 鏈接操做符: +

1.3 重複操做符: *… sequence * int

1.4 切片操做符: (利用子序列方式結合三種操做方式, 能夠很是靈活的控制序列)

1.4.1 [], 索引取值

1.4.2 [start : end], 索引範圍取值

1.4.3 [::step], 切片的步長

1.4.4 切片操做符不會帶來索引超出下標的異常

2 list.extend(iterable): 把另一個序列追加到list中.

3 list.insert(index, object): 把一個元素object插入到list的index位置, 若是index是負數, 從後面向前數, 超過list下標後, 在末尾添加

4 類型轉換

4.1 list(iter)  把可迭代對象轉換爲列表

4.2 str(obj)  把obj對象轉換成字符串(對象的字符串表示法)

4.3 unicode(obj)  把對象轉換成Unicode字符串(使用默認編碼), 使用u」漢字」能夠獲得其unicode編碼

4.4 basestring()  抽象工廠函數, 不能被實例化, 不能被調用, 僅做爲str和unicode的父類

4.5 tuple(iter)  把一個可迭代對象轉換成元組對象

4.6 enumerate(iterable)  生成由iterable每一個元素的index值和item值組成的元組, 能夠使用for key, value in enumerate的方式進行迭代

4.7 max(iterable, key=None) | max(arg0, arg1, …, key=None) 返回iterable或arg0…中的最大值, 若是要指定key, 必須是一個能夠傳遞給sort()方法的回調函數…..要使用key, 必須使用key=method_name的方式傳參, key指定的函數接收的參數是迭代的當前元素, 在該函數中, 對元素進行處理, 返回一個對象, python會根據返回對象比較大小, 獲得該結果最大的元素對應的list中的元素

4.8 min同上面的max方法.  對於max和min方法, 若是是自定義類型, 又沒有指定key, 那麼默認是按照id(object)的結果計算的

4.9 reversed(sequence)  返回逆序訪問的迭代器

4.10 sum(sequence, init=0)  返回sequence和可選參數init的總和, 等同於reduce(operator.add, sequence, init)

4.11 sorted(iterable, func=None, key=None, reverse=False)  接受一個可迭代對象, 返回一個有序列表, 可選參數func, key, reverse含義和list.sort相同

4.12 zip([item0, item1, …, itemn])  返回一個列表, [(item0, ), (item1, ), …, (itemn, )]

4.13 sort(cmp=None, key=None, reverse=False)  將序列進行排序, cmp指定一個接受兩個參數的回調函數, 該函數獲得的兩個參數是序列中的兩個元素, 比較將按照cmp指定的回調函數進行, 返回數字類型的比較結果, , , key指定一個接受一個參數的回調函數句柄, 該參數就是迭代到的元素, 在比較以前, 將會根據這個回調函數對要比較的元素進行一次處理, 實際參與比較的是通過該回調函數處理以後的返回值.  reverse指示是否對比較結果進行逆序

5 利用已有功能函數定義動態參數的函數: method = lambda x, y: cmp(x + 10, y - 10), 調用時仍是使用句柄加參數的方式: method(x, y)

6 字符串: 若是先使用切片操做, 子串會被在內存中進行短期的暫存, 能夠經過id()獲得值

7 比較: 普通字符串按照ascii值比較, Unicode字符串按照unicode值比較.

8 字符串切片, 下圖是字符串切片的索引值, 若是開始或結束的索引值沒有指定, 默認爲0, 或-1. [::step]用於指定步長

 

9 成員操做符: in, not in, 能夠判斷一個子串是否在字符串中存在…使用find(), index(), rfind(), rindex()能夠得到子串在源中的位置

10 string模塊有一些預約義的字符串: ascii_letters, ascii_lowercase, ascii_uppercase, digits

11 循環的改善: 若是循環的終止條件是不變的(通常都是不變的), 那麼儘可能不在循環終止條件中調用方法是一個好的習慣, 在大量數據的狀況下(5 * 10^8數據), 改善的循環效率提高了4秒左右, 平均計算獲得改善後循環每次效率提高約爲7.154 * 10^-8s 也就是71.54 ns

12 for-else方式的循環, else子句會在全部的元素都被循環完成以後執行, 若是break, 就不執行

13 join能夠用來鏈接字符串, 這樣的效率是更高的, 由於+鏈接必須爲每一個字符串建立內存

14 +鏈接字符串是運行時鏈接, 「str1」」str2」的方式則是編譯時鏈接字符串

15 普通字符串和unicode字符串鏈接, 會把普通字符串轉換成unicode字符串進行鏈接

16 %格式化字符串的參數:

16.1 %c  轉換成字符(ascii值, 或長度爲一的字符串)

16.2 %r  優先使用repr()函數進行字符串轉換

16.3 %s  優先使用str()函數進行字符串轉換

16.4 %d / %i  轉成有符號的十進制數

16.5 %u  轉成無符號的十進制數  遇到負號添加-號

16.6 %o  轉成無符號八進制數  遇到負號添加-號

16.7 %x / %X  轉成無符號十六進制數(x|X的大小寫決定轉換後獲得十六進制數中的字母的大小寫)   遇到負數, 則轉換獲得的結果中添加一個-號

16.8 %e / %E  轉成科學計數法(e | E的大小寫決定轉換後獲得的e的大小寫)

16.9 %f / %F  轉成浮點數(小數部分天然截斷)

16.10 %%  輸出%號

17 其餘格式化操做符輔助指令(位於%和格式化標識的中間)

17.1 *  定義寬度或小數點精度"adfas%*dfasdf" % (5, 2.000000888)

17.2 –  用於左對齊    

17.3 +  在正數前加+號

17.4 (sp)  在正數前顯示空格

17.5 #  在八進制前加0, 十六進制前顯示0x或0X, 取決於用的是x或X    好比: "integer:%#X!" % 1984

17.6 (var)    映射變量(字典參數)

17.7 m.n   m是顯示的最小總寬度, n是小數點後的位數

18 格式化字符串接收dict數據:」%(howmany)d days」 % {「howmany」: 28}

19 字符串模板 s = Template(‘There are ${howmany} ${lang} Quotation Symbols’)

19.1 s.substitute([key = value, key = value…])  這個函數必須提供全部的佔位參數, 不然報錯

19.2 s.safe_substitute([key = value, key = value…])  和substitute功能是同樣的, 都是轉成獲得一個字符串, 可是這個方法對參數沒有要求, 若是沒有提供對應的參數, 就直接輸出.

20 原始字符串操做符(r/R), 緊貼字符串左引號, 不區分大小寫. 用來使字符串描述各自原始的意義, 而不使用轉義

21 使用正則查找空白字符: m = re.search(r‘\\[rtfvn]’, r’Hello World!\n’)…

22 能夠使用u | U ‘字符串’的方式建立unicode字符串, 該標識能夠和r/R連用

23 python參數有位置參數和關鍵字參數兩種, 位置參數在定義時只有參數名, 關鍵字參數定義時是key=value的形式

24 python也提供可變參, *爲位置可變參, **爲關鍵字可變參

25 若是使用* | **方式傳遞實參, * 能夠將序列參數轉變成每一個元素做爲單獨參數, **則能夠將dict轉換成關鍵字參數

26 內建函數

26.1 cmp, 使用字符的ascii值進行比較(Unicode字符串按照unicode值比較)

26.2 max, min, len, enumerate, zip, 其中zip能夠接受多個參數, 按照下面方式返回:

zip(「abcd」, 「efg」, 「hijk」, 「lmn」) 返回: [('a', 'e', 'h', 'l'), ('b', 'f', 'i', 'm'), ('c', 'g', 'j', 'n')]

26.3 str和unicode都是basestring的特化類, 可是, Unicode又包含(類之間僅僅是兄弟關係, 元素範圍上有包含關係)str的表示範圍

26.4 chr(number), unichr(number), ord(string), chr和unichr分別用來把一個數字轉換成一個對應類型的字符串, ord則是將一個string類型的單字符對象轉換成爲對應的ascii碼或unicode編碼

27 string模塊的重要函數, 全部這些函數, 均可以省略第一個參數, 使用string.func的方式調用

27.1 string.index()和string.find()方法是同樣的功能, 可是, index方法在查找不到字符串的時候, 會報一個異常, string.rfind(), string.rindex()用法相同, 是從右邊開始查找

27.2 string.join(sequence[, str]) 若是隻有一個參數, 返回一個將全部元素插空一個空格的字符串(若是是序列, 轉換成爲字符串), 若是有兩個參數, 把第二個參數向第一個參數的每一個空位進行插空

27.3 string.ljust(string, width[, fillchar])  填充fillchar(只能是一個字符)width個到string後面, 使string左對齊, 若是fillchar空, 填充空格, rjust爲右對齊

27.4 string.lower(), string.upper(), string.swapcase()大小寫轉換

27.5 string.lstrip(), string.rstrip(), string.strip()  去除空格.

27.6 string.split(string, sub, count)  將string截取sub, 從左向右截取count個, 返回list

27.7 string.replace(string, old, new[, number=string.count(string, old)])  將string的old子串替換成new, 最多替換不超過number, number默認是old在string的數量

27.8 string.translate

27.9 string.zfill(string, width)  用width個0填充string的左面使其右對齊

28 unicode.encode(CODE_STRING) 按照指定編碼方式編碼字符串, decode反之, 按照指定編碼方式解碼

29 除了pickle模塊以外, 其餘模塊都已經支持unicode..

30 UnicodeError異常在exceptions模塊中定義, 是ValueError的子類, 全部關於Unicode編解碼的異常都要繼承自UnicodeError

31 與字符串類型有關的模塊:

31.1 string: 字符串相關操做函數和工具, 好比Template類

31.2 re:  正則表達式

31.3 struct: 字符串和二進制之間的轉換

31.4 c/StringIO  字符串緩衝對象, 操做方法相似於file對象

31.5 base64  Base16, 32, 64數據編解碼

31.6 codecs   解碼器註冊和基類

31.7 crypt  進行單方面加密

31.8 difflib   找出序列間的不一樣

31.9 hashlib   多種不一樣安全哈希算法和信息摘要算法的API

31.10 hma    HMAC信息鑑權算法的python實現

31.11 md5  RSA的MD5信息摘要鑑權

31.12 rotor   提供多平臺的加解密服務

31.13 sha    NIAT的安全哈希算法SHA

31.14 stringprep   提供用於IP協議的Unicode字符串

31.15 textwrap   文本打包和填充

31.16 unicodedata    Unicode數據庫

32 字符串的關鍵點:

32.1 不可分字符類型

32.2 相似printf()的格式化字符串

32.3 三引號內能夠接受特殊字符(What You See Is What You Get)

32.4 r | R原始字符串

32.5 python字符串不經過NUL或者\0結束

33 list的元素刪除

33.1 del list[index]  根據index刪除list中的元素

33.2 list.remove(value)   從list中移除值是value的第一個元素

33.3 list.pop()   相似棧的出棧操做, 彈出棧頂並返回

34 list的成員關係操做仍是使用in | not in

35 列表解析: [var_name for var_name in list if expression]if以後和for以前均可以使用var_name進行運算

36 列表的比較操做, 隱式調用cmp方法, 比較規則是逐個掃描元素, 進行比較, 若是能夠比較, 比較, 若是相等掃描下一個元素, 若是不相等返回結果, 若是兩個元素類型不能夠比較, 就比較兩個對象的id()值.. 若是一直相等 ,直到一個列表掃描結束, 那麼返回較長的列表較大

37 序列類型函數

37.1 len(), max(), min()

37.2 sorted() 和reversed()  返回的是被排序或逆序以後的序列, 不會改變序列自己的引用, 而序列本身的成員方法則會改變自身

37.3 enumerate()  返回一個key=>value方式的enumerate對象

37.4 zip()  將多個列表壓縮成爲一個元組列表…..zip返回的元組列表能夠使用足夠元組內元素數量的參數來迭代遍歷每個元素, 例如: for a, b, c, d in zip(alist, blist, clist, dlist)

37.5 使用list()和tuple()能夠完成列表和元組之間的轉換, 可是這種轉換是值的轉換, 因此他們是==的, 可是不是is的

37.6 extend(列表)方法接受另一個列表追加到原列表以後

37.7 list.pop(index = -1)  list的pop能夠彈出指定索引的值

38 處理一組對象的時候, 默認的是建立一個元組, 例如a = 1, 2, 3, 4 其實是建立了一個元組(1, 2, 3, 4)

39 單獨使用del刪除一個元組元素是不可行的, 只能經過重組

40 元組的可變性: 元組的某一個元素指向了一個對象, 該對象是可變的, 那麼改變該對象就至關於改變了元組的內容, 然而, 真正的咱們的元組確實是沒有改變的. It’s so wizardly. 爲何呢? 元組內部持有的是對方的引用, 那個對象不管怎麼變都仍是在那裏, 因此, 元組內部的值(內存地址)是沒有改變的.

41 函數能夠返回多對象, 返回的實際也是一個元組

42 單元素元組使用括號建立時須要在後面顯示的加上」, 」, 因爲括號被重載做爲一個分組操做符了, 在這裏會優先使用分組功能, 因此, 返回的老是原始類型

43 相關模塊:

43.1 數組array   受限的可變序列類型, 要求全部元素都是相同的類型

43.2 operator   包含函數調用形式的序列操做符, operator.concat(m, n)至關於m+n

43.3 re  perl風格的正則查找

43.4 StringIO / cStringIO  長字符串做爲文件來操做, 好比read(),  seek()函數……c版本的速度更快一些

43.5 Textwrap  包裹/填充文本的函數

43.6 types   包含python支持的全部類型

43.7 collections  高性能容器數據類型

43.8 UserList  包含了list對象的徹底的類實現, 容許用戶得到相似list的類, 用以派生新的類和功能

44 淺拷貝: 拷貝原對象中的內容, 可是新建立對象. 好比一個list的淺拷貝就是把list中元素的引用值拷貝過去…  淺拷貝實例: 徹底切片操做, 利用工廠函數, 使用copy模塊的copy函數

45 深拷貝: 拷貝源對象中的內容, 若是某個屬性(或序列中的元素)是可變對象, 把該可變對象的內容也進行拷貝

46 非容器類型對象沒有拷貝一說

47 可變參: f(*args1, **args2), 若是關鍵字可變參不指定key值, 會被做爲位置參數和前面的參數放到一個元組中….位置可變參在倒數第二個位置, 關鍵字可變參在倒數第一個位置.

48 map(function, iterable), 應用function在iterable的每個元素, 返回值做爲新的序列的元素

映射和集合類型(chapter7)

1 字典使用keys()得到鍵的列表, values()得到值的列表, items()得到包含key->value對的元組的列表

2 字典的建立和賦值

2.1 dict = {key: value}

2.2 dict = dict((key, value), (key, value))

2.3 dict.fromkeys(sequence_keys, default_value) 建立一個key是sequence_keys中元素的字典, 全部的value都是default_value, 若是不指定default_value, 默認是None

3 使用dict.has_key()能夠判斷一個字典中是否有這個鍵, 該方法在後期python可能棄用, 推薦使用in和not in

4 字典的鍵必須是可哈希的

5 print中使用到字典的時候, 使用字符串格式化方式是很是優雅的

6 dict1.update(dict2 | tuple_list[, **key=value])

6.1 將dict2字典更新到dict1中

6.2 若是參數是一個元組列表, 將元組列表解析到dict1中(元組列表中每一個元組必須有兩個元素)

6.3 能夠在參數後面跟0—n個關鍵字參數, 以參數名: value的方式更新到dict1中

7 元素的刪除

7.1 del dict[「key」] 刪除鍵是key的條目

7.2 dict.clear()  清空字典內的內容

7.3 dict.pop(「name」)  刪除鍵是key的條目並返回

8 映射類型操做符

8.1 標準類型操做符: <, >等比較操做符能夠使用, 在比較過程當中, 仍是調用了字典的cmp方法, 可是, 字典的cmp方法中指示, 首先比較字典的長度, 而後比較鍵的大小, 最後比較值的大小

8.2 字典查找操做: [], 成員關係操做: in, not in

9 dict工廠函數

9.1 接受不定關鍵字參數: dict(a = 1, b = 2, c = 3)

9.2 接受字典或關鍵字參數: 將原有的字典拷貝出來成爲一個新的字典(這裏使用的淺拷貝, 這裏的淺拷貝獲得的結果和使用copy函數獲得的結果是同樣的,可是, copy函數的效率更高)

9.3 dict_instance.copy() 使用已有的字典拷貝一個字典(這裏使用的也是淺拷貝)

10 系統內建函數

10.1 len(): 返回字典的key-value對的數目

10.2 hash(): 這個函數不是爲字典設計的, 可是它能夠判斷某個對象是否能夠作一個字典的鍵, 將一個對象做爲參數傳遞給hash(), 會返回這個對象的哈希值.  若是對象是不可哈希的, 會返回TypeError, 提示該對象是unhashable的

10.3 sorted(dict):  返回dict的全部key排序後的列表

11 dict類型的內建方法

11.1 keys(): 返回字典的全部key的列表

11.2 values(): 返回字典的全部value的列表

11.3 items(): 返回字典的全部key-value的元組的列表

11.4 get(key, default = None):  獲取字典內key對應的值, 若是沒有該key, 返回default指定的默認值

11.5 setdefault(key, default=None): 若是字典中不存在key, 由dict[key]=default爲其賦值

11.6 iterkeys(), itervalues(), iteritems() 對應沒有iter命名的方法, 這裏使用了惰性賦值的迭代器, 節省內存

12 數字做爲字典的鍵的時候, 只要值相同, 就表明相同的鍵, 好比, 1, 和1.0表明的就是相同的鍵

13 鍵必須是可哈希的, 全部的不可變對象都是可哈希的, 可變對象若是在定義中定義了__hash__()方法, 那麼就能夠做爲鍵

14 若是元組中的值都是不可變類型的, 那麼元組也能夠做爲字典的鍵

15 集合sets有兩種不一樣的類型, 可變集合set和不可變集合frozenset…可變集合也是不可哈希的…

16 集合中不能有重複的元素, 若是有元素和已有元素重複, 就不會被插入.集合是無序的, 可是, 能夠使用排序函數爲它排序

17 集合中能夠使用的數學符號

 

18 集合只能使用工廠函數set和frozenset建立

19 訪問集合中的數據使用循環, 或者使用成員關係操做符in, not in判斷元素是否屬於集合

20 更新集合(只能是set, frozenset不能被更新)

20.1 add()  添加一個元素

20.2 s.update()  接受一個序列類型的參數, 把該序列中有而集合中沒有的元素添加到集合中

20.3 s.remove()  從集合中移除一個元素

21 集合可用的標準類型操做符

21.1 成員關係: in, not in

21.2 集合等價/不等價: ==, !=

21.3 子集/超集: <, <=, >, >=

22 集合類型操做符(全部的集合類型)  集合互相操做的時候, 最後產生的集合是可變集合仍是不可變集合取決於第一個參與操做的集合的類型

22.1 聯合 |

22.2 交集 &

22.3 差補/相對補集  -  A-B就返回屬於A 但不屬於B的元素集合

22.4 對稱差分   ^  A^B = A-B + B-A

23 可變集合特有的操做符

23.1 |=  至關於update方法, 並集賦值

23.2 &=  至關於intersection_update()方法, 交集賦值

23.3 -=   至關於difference_update()方法, 差集賦值

23.4 ^=  至關於symmetric_difference_update()方法, 對稱差分更新

24 集合類型的內部方法:

24.1 s.issubset(t)  判斷s是否是t的子集

24.2 s.issuperset(t)  判斷s是否是t的超集

24.3 s.union(t)   返回一個新集合, 該集合是s和t的並集

24.4 s.intersection(t)  返回一個新集合, 該集合是s和t的交集

24.5 s.difference(t)  返回一個新集合, 該集合是s的成員, 但不是t的成員, 即返回s不一樣於t的元素

24.6 s.symmetric_defference(t)  返回全部s和t獨有的(非共同擁有)元素集合

24.7 s.copy()  返回一個s的淺拷貝, 效率比工廠要好

25 可變集合特有的方法: add, remove, discard, pop, clear, 這些接受對象的方法, 參數必須是可哈希的

26 那些和操做符提供相同功能的函數, 有着更強的處理能力, 由於運算符兩邊的操做數必須都是集合, 然而函數能夠接受任何的可迭代類型.

條件和循環(chapter8)

1 若是循環體, 或條件語句體只有一句, 能夠和頭寫在同一行.

2 字典的搜索速度要比for, if, while等快得多

3 True and object, 返回object, True or object 返回True, 所以能夠使用expression and out1 or out2 模擬三元操做符

4 python提供的三元操做: X if C else Y, 若是c輸出x, 不然輸出y

5 xrange()不會在內存中建立列表的完整拷貝, 只被用在for循環中.

6 reversed()和enumerate()內建函數返回的是一個迭代器

7 迭代器的優勢

7.1 提供了可擴展的迭代器接口

7.2 對列表迭代帶來了性能上的加強

7.3 在字典迭代中性能提高

7.4 建立真正的迭代接口,而不是原來的隨機對象訪問

7.5 與全部已經存在的用戶定義的類以及擴展的模擬序列和映射的對象向後兼容

7.6 迭代非序列集合(例如映射和文件)時, 能夠建立更簡潔的代碼

8 迭代器工做原理: next()方法取出元素, 元素所有取完後觸發StopIteration異常, for能夠根據異常結束循環

9 any(), all()用來判斷序列或迭代器中元素的真假, any爲或操做, all爲與操做

10 iter(iterable) 用來建立一個迭代器

11 文件的迭代器中調用next方法, 默認會調用readline方法.  若是直接使用for line in file就能夠建立一個默認的文件迭代器.

12 在迭代的時候, 不要嘗試改變可變對象

13 列表解析:

13.1 lambda, 動態建立函數

13.2 map(function, sequence), 對sequence的每個元素應用function, 返回一個新的列表

13.3 filter(function, sequence), 對sequence的每個元素應用function, 某個元素應用該function後若是返回false, 該元素將被從最後返回的列表中過濾掉

13.4 列表解析中能夠使用多個循環, 來達到生成矩陣或多維序列的目的..例如【(x, y) for x in range(5) for y in range(3)】 越靠後的循環就至關於普通循環中的內層循環

14 生成器

14.1 生成器表達式和列表解析表達式是同樣的, 可是生成器表達式沒有中括號, 單獨使用的時候, 使用圓括號, 做爲參數的時候, 不須要圓括號

14.2 生成器表達式能夠被用做迭代

14.3 生成器表達式是lazy的

14.4 示例: 獲取文件的最長的行的長度: logest = max(len(line.strip()) for line in file)

文件和輸入輸出(chapter9)

1 文件只是連續的字節序列

2 file_object = open(file_name, access_mode = ‘r’, buffering = -1) mode有r, w, a, 分別表示讀取, 寫入, 追加.  U模式表明通用換行符支持

2.1 使用r, U打開的文件必須是已經存在的,  使用w打開的文件若是存在, 首先清空…使用a模式打開的文件是爲追加數據作準備, 全部寫入數據被追加到文件末尾.  +表明可讀可寫, b表明二進制訪問… POSIX兼容的Unix系統中, ‘b’是無關緊要的, 由於它們把全部的文件都看成二進制文件.  包括文本文件

2.2 若是在mode中要使用b, b不能做爲第一個字符出現

2.3 buffering, 表示緩衝區大小, 0表示不緩衝, 1表示只緩衝一行數據, 其餘大於1的值表示使用定值做爲緩衝區大小.  不提供該參數或給定負值表明使用系統默認的緩衝機制

2.4 訪問模式:

2.4.1 r  只讀方式打開

2.4.2 rU或Ua  讀方式打開, 同時提供通用換行符支持

2.4.3 w  寫方式打開

2.4.4 a  追加模式打開, 必要時建立新文件

2.4.5 r+  讀寫方式打開

2.4.6 w+  讀寫方式打開

2.4.7 a+  讀寫方式打開

2.4.8 rb  二進制讀模式打開

2.4.9 wb  二進制寫模式打開

2.4.10 ab  二進制追加模式打開

2.4.11 rb+  二進制讀寫模式

2.4.12 wb+  二進制讀寫模式

2.4.13 ab+  二進制讀寫模式

3 file()內建函數和open的使用方式同樣…可是推薦使用open, 除非特定的要處理文件對象時, 使用file()內建函數

4 通用換行符支持: 任何系統下的文件, 無論換行符是什麼, 使用U模式打開時, 換行符都會被替換爲NEWLINE(\n)

5 python默認打開UNS, 若是不須要通用換行符支持, 在運行configure腳本時, 能夠使用—without-universal-newlines 開關關閉.

6 文件方法:

6.1 輸入

6.1.1 read(size=-1): 直接讀取字節到字符串中, 最多讀取給定數目個字節.  不指定size參數, 或size值爲負, 文件將被讀取到末尾.  

6.1.2 readline(size = -1)  size爲負數或不指定, 讀取至行末, 若是指定了其餘的size值, 讀取size個字節   讀到的換行符不會自動去掉, 而把這個操做留給程序員, 使用strip去掉

6.1.3 readlines(sizhint = -1)  sizhint和size功能相同, 若是指定, 會讀取sizhint個字節, 實際讀取值可能比sizhint較大, 由於須要填充緩衝區

6.1.4 file.xreadlines()和xreadlines.xreadlines(file) 是一種更高校的文件讀取, 一次讀取一塊, 而不是一次讀取全部行, 可是, 因爲iter取代了該功能, 因此會被廢棄.

6.2 輸出

6.2.1 write()  把含有文本數據或二進制數據塊的字符串寫入到文件中

6.2.2 writelines() 接受一個字符串列表做爲參數, 將他們寫如文件, 行結束符不會自動加入, 若是須要, 必須在調用writelines以前手動在每行結尾加上換行符

6.2.3 seek(offset, whence)  隨機文件訪問, 第一個參數offset表示偏移量, 第二個參數表示位置, 即第一個參數相對哪裏去偏移

6.3 迭代: 直接彷佛用for循環迭代

6.4 其餘:

6.4.1 close()  關閉文件結束對它的訪問.  垃圾回收機制也會在文件對象的引用計數降至0的時候自動關閉文件.

6.4.2 fileno()  返回打開文件的描述符…是一個整數, 能夠用在如os模塊的read方法等一些底層操做上.

6.4.3 flush()方法直接把內部緩衝區的數據馬上寫入文件, 而不是被動的等待輸出緩衝區寫入.

6.4.4 tell()方法返回文件的當前位置, 對應seek方法的offset參數

6.4.5 isatty() 是一個布爾內建函數, 當文件是一個類tty設備時返回true, 不然返回false.

6.4.6 truncate()方法將文件截取到當前文件指針位置或者到給定size, 以字節爲單位

6.4.7 next()  返回文件的下一行

7 os模塊的重要屬性

7.1 linesep   跨系統的分隔行的字符

7.2 sep   分割文件路徑名的字符串( / \   路徑內的不一樣級分割)

7.3 pathsep   分割文件路徑的字符串(;  多個路徑分割)

7.4 curdir   當前工做目錄的字符串名稱(. )

7.5 pardir  當前工做目錄的父目錄的字符串名稱(.. )

8 文件的內建屬性:

8.1 name  文件名, 打開文件或使用file()工廠的時候傳遞的文件名參數

8.2 mode  打開模式

8.3 closed  是否已經關閉

8.4 encoding   編碼方式, None表示使用系統默認的編碼

8.5 newlines  未讀取到行分隔符時爲None, 只有一個種行分割符時爲一個字符串, 當文件有多種類型的行結束符時, 則爲一個包含全部當前遇到的行結束符的列表

8.6 softspace  0表示在輸出一數據後, 要加上一個空格符, 1表示不加

9 標準文件, sys模塊下的stdin, stdout, stderr分別是標準輸入文件(鍵盤), 標準輸出文件(緩衝的屏幕輸出), 標準錯誤(到屏幕的非緩衝輸出)  這三個文件是預先打開的, 能夠直接使用

10 sys.argv是命令行參數的列表, 列表中第一個是當前python腳本的名稱, 後面分別是python腳本在命令行下被調用時傳入的參數, 相似於java的main方法接受的參數, len(sys.argv)是命令行參數的個數

11 其餘提供命令行參數的輔助處理模塊:

11.1 getopt模塊, 簡單的命令行參數處理

11.2 optparse模塊, 複雜的命令行參數處理.

12 os模塊: 全部操做系統對外的門面, 主要提供刪除/重命名文件, 遍歷目錄樹, 管理文件訪問權限等功能

12.1 文件處理

12.1.1 mkfifo()/mknod()  建立命名管道/建立文件系統節點

12.1.2 remove()/unlink()  刪除文件, 指定路徑爲參數進行刪除, 若是文件不存在會拋出異常

12.1.3 rename()/renames()  重命名文件, 接受舊文件路徑和新文件路徑, 進行名字的修改, 這裏能夠經過指定新的路徑達到文件移動的目的. 沒有發現renames和rename的區別

12.1.4 stat()  返回文件信息, 包含文件的mode, 編號, 用戶(建立者, 全部者, 組), 時間等信息

12.1.5 symlink()  建立符號連接   ….已經廢除???

12.1.6 utime()  更新時間戳

12.1.7 tmpfile()  建立並打開(‘w+b’)一個新的臨時文件  沒有參數, 直接獲取一個臨時文件

12.1.8 walk(top, [topdown=True[, onerror=None[, followlinks=False]]]) 生成一個目錄樹下的全部文件名.

12.1.8.1 該方法用於生成目錄樹下的全部子文件名, 該方法返回一個生成器, 遍歷生成器能夠獲得一個三個元素的元組(dirpath, dirnames, filenames)

12.1.8.2 返回元素元組中的dirpath是top的目錄名, dirnames是top下全部子目錄的文件名集合, 不包含當前目錄.和上級目錄.., filenames是top下的全部的非目錄類型的文件的名字集合

12.1.8.3 walk返回元組中的名字集合能夠使用os.path.join(dirpath, name)獲得一個文件或目錄的全路徑.

12.1.8.4 walk返回的生成器包含了top目錄之下全部子孫目錄的內部結構

12.1.8.5 walk的第二個參數topdown指示了對該目錄樹的遍歷是否採用自上而下的方式, 默認是True

12.1.8.6 walk的第三個參數是指示錯誤發生時是否處理, 接收的是一個回調函數, 函數會獲得一個參數OSError的實例

12.1.8.7 walk的第四個參數是指示是否遍歷link類型指向的目錄, 默認是false, 可是, 若是你設置了followlinks=True, 並有一個link是指向它的父親或更高輩分的目錄, 就會產生一個無窮遞歸.

12.1.8.8 注意:  若是使用walk的時候傳遞了一個相對路徑, 在從新開始walk以前, 不要改變工做目錄..  當前工做路徑的改變會致使walk中止工做

12.2 目錄/文件夾處理

12.2.1 文件的fileno()返回該文件的文件描述符

12.2.2 chdir()/fchdir()  改變當前工做目錄/經過一個文件描述符改變當前工做目錄

12.2.3 chroot()  改變當前進程的根目錄

12.2.4 listdir()  列出指定目錄的文件, 返回參數指定的路徑下的全部文件和目錄, 不包括當前目錄.和父親.., 也不進行遞歸

12.2.5 getcwd()/getcwdu()  返回當前工做目錄/功能相同, 但返回一個unicode對象

12.2.6 mkdir()/makedirs()  建立目錄/建立多層目錄, 接受兩個參數, 一個表示路徑, 一個表示模式(權限???)  mkdir()只能用於建立一級目錄, 若是父目錄不存在會拋出異常, 而makedirs()會向上遞歸的建立目錄

12.2.7 rmdir()/removedirs()  刪除目錄/刪除多層目錄  rmdir刪除一個目錄或文件, removedirs()則遞歸刪除一個目錄樹, removedirs()是一個難懂的函數, 指定一個父親沒法刪除父親下的全部孩子, 反而由孩子刪除了本身的父親和祖輩

12.3 訪問/權限

12.3.1 access()  檢驗權限模式, 兩個參數, 第一個是路徑, 第二個是模式, 模式能夠是F_OK, 用來檢測路徑是否存在, R_OK用來檢測是否可讀, W_OK用來檢測是否可寫, X_OK用來檢測是否可執行.  返回布爾值表示檢驗結果

12.3.2 chmod()  改變權限模式  接受兩個參數, 第一個是路徑, 第二個是模式, 模式在stat模塊下定義, 是一些數字類型表明的模式, 主要是針對linux下的權限控制, 儘管windows下也支持這個方法, 可是, 只有stat.S_IREAD, stat.S_IWRITE纔會起到真正的做用.

12.3.3 chown()/lchown()  改變owner和group Id / 功能相同, 但不會跟蹤連接….或許這個方法windows平臺不支持??? 接受三個參數, 第一個是路徑, 第二個是用戶id, 第三個是組id

12.3.4 umask()  設置默認權限模式 接受一個數字類型的參數, 設置新的默認權限模式, 並返回以前的權限模式.

12.4 文件描述符操做

12.4.1 open()  底層的操做系統open

12.4.2 read()/write()  根據文件描述符讀取/寫入數據

12.4.3 dup(file_descriptor)/dup2(file_descriptor, file_descriptor2)  dup返回file_descriptor的複製品, dup2則是把file_descriptor複製到file_description2

12.4.3.1 每一個進程在進程表中有一個記錄項, 每一個記錄項中有一張打開文件描述符表, 能夠看做是一個矢量, 每一個描述符佔用一項, 與每一個文件描述符相關聯的是:

12.4.3.1.1 文件描述符標誌

12.4.3.1.2 指向一個文件表項的指針

12.4.3.2 內核爲全部打開文件維持一張文件表, 每一個文件表項包含

12.4.3.2.1 文件狀態標誌(讀, 寫, 增寫, 同步, 非阻塞等).

12.4.3.2.2 當前文件位移量

12.4.3.2.3 指向該文件v節點表項的指針

12.4.3.3 習慣上, 標準輸入(STDIN_FILENO)的文件描述符是0, 標準輸出(STDIN_FILENO)的文件描述符是1, 標準錯誤(STDERR_FILENO)的文件描述符是2

12.4.3.4 文件描述符是非負整數, 打開現存文件或新建文件時, 內核會返回一個文件描述符, 讀寫文件也須要使用文件描述符來指定待讀寫的文件

12.4.3.5 文件描述符的有效範圍是0 ---- open_max, 通常, 每一個進程最多打開65個文件, freebsd5.2.1, mac os x 10.3和solaris9則支持每一個進程打開最多文件數和內存, int的大小, 管理員設定有關, linux2.4.22強制規定最多不超過1048576個.

12.4.3.6 fdopen(file_descriptor[, mode[, fuffer_size]])  經過指定文件描述符, 模式, 緩衝區大小打開一個文件.  因爲緩衝區的存在, 最後須要顯示的flush()一下以清空緩衝區

12.4.3.7 dup2(fd, fd2)  表示fd和fd2共享同一個文件表項, 也就是說他們的文件表指針指向了同一個文件表項, 所以他們也就是共享了相同的文件i/o…第一個參數必須是已經存在的而且打開的合法的文件描述符, 而第二個參數能夠是任意的文件描述符

12.4.3.8 dup(fd)  返回一個和文件描述符fd一樣的文件描述符, 這裏是爲了備份文件描述符, 當一個文件描述符使用dup2進行重定向以前, 咱們應該首先用dup拷貝一份出來備份, 須要恢復的時候進行再次重定向.  它的語義是:  返回一個新的文件操做符, 和原來的文件操做符fd共享一個文件表項

12.5 設備號

12.5.1 makedev()  從major和minor設備號建立一個原始設備號

13 os.path模塊的路徑名訪問函數

13.1 分隔

13.1.1 basename()  去掉目錄路徑, 返回文件名

13.1.2 dirname()  去掉文件名(本身的名字, 若是是文件夾就是文件夾名), 返回目錄路徑

13.1.3 join()  將分離的各部分組合成一個路徑名…能夠接受不定數量個參數.

13.1.4 split()  返回一個元組, 第一個元素是目錄名, 第二個元素是文件名(或最後一層的文件夾名)

13.1.5 splitdrive()  返回一個元組, 第一個元素是該路徑所屬的設備號(好比C盤), 第二個元素是相對該設備的相對路徑

13.1.6 splitext()  返回一個元組, 第一個元素是該路徑的全路徑(不含文件後綴名, 若是末級是文件夾, 第二個元素爲空), 第二個元素是文件的後綴名

13.2 信息

13.2.1 getatime()  返回最近訪問時間  這裏的返回時間的方法都是返回int型的秒數

13.2.2 getctime()  返回文件建立時間

13.2.3 getmtime()  返回最近文件修改時間

13.2.4 getsize()  返回文件大小

13.3 查詢

13.3.1 exists()  斷定文件/目錄是否存在

13.3.2 isabs()  斷定路徑是不是絕對路徑

13.3.3 isdir()  斷定路徑是否存在且爲一個目錄

13.3.4 isfile()  斷定路徑是否存在且爲一個文件

13.3.5 islink()  斷定路徑是否存在且爲一個符號連接

13.3.6 ismounts()  斷定路徑是否存在且爲一個掛載點

13.3.7 samefile(path1, path2)  斷定兩個路徑名是否指向同一個文件

14 永久存儲模塊

14.1 pickle和marshal: 一組最小化永久性存儲模塊(序列化). 能夠用來轉換並存儲python對象.  是將python的對象轉換成一個二進制數據集合保存起來, 能夠經過網絡發送, 而後從新把數據集合恢復成原來的對象格式, 也就是java中的序列化.

14.2 marshal和pickle模塊的區別在於marshal只能處理簡單的python對象(數字, 序列, 映射, 代碼對象), 而pickle還能夠處理遞歸對象, 被不一樣地方屢次引用的對象, 以及用戶定義的類和實例...

14.3 pickle模塊還有一個加強的版本叫cPickle

14.4 *db*系列的模塊使用傳統的DBM格式寫入數據… python提供了dbhash/bsddb, dbm, gdbm, dumbdbm等多個DBM實現.  若是不肯定, 使用anydbm模塊, 它會自動檢測系統上已經安裝的DBM兼容模塊, 選擇’最好’的一個.  dumbdbm模塊是功能最少的, 沒有其餘模塊可用時, anydbm纔會選擇它….這些模塊的不足指出在於他們只能存儲字符串, 不能對python對象進行序列化

14.5 shelve模塊使用anydbm模塊尋找合適的DBM模塊, 而後使用cPickle完成對儲存的轉換過程. shelve模塊容許對數據庫文件進行併發的讀訪問, 但不容許共享讀/寫訪問.

 

14.6 pickle的使用

14.6.1 dump(obj, file, protocol = None): 接受一個數據對象和一個文件, 把數據對象以特定的格式保存到給定的文件裏.

14.6.2 load(file)  從文件中取出已經保存的對象.

15 相關模塊:

15.1 base64  二進制字符串和文本字符串之間的編碼/解碼操做

15.2 binascii  二進制和ascii編碼的二進制字符串間的編碼/解碼操做

15.3 bz2  訪問BZ2格式的壓縮文件

15.4 csv  訪問csv文件(逗號分割文件)

15.5 filecmp   用於比較目錄和文件

15.6 fileinput  提供多個文本文件的行迭代器

15.7 getopt/optparse  提供了命令行參數的解析/處理

15.8 glob/fnmatch  提供Unix樣式的通配符匹配功能

15.9 gzip/zlib   讀寫GNU zip(gzip)文件(壓縮須要zlib模塊)

15.10 shutil  提供高級文件訪問能力

15.11 c/StringIO   對字符串對象提供類文件接口

15.12 tarfile  讀寫TAR歸檔文件, 支持壓縮文件

15.13 tempfile   建立一個臨時文件(名)

15.14 uu  格式的編碼和解碼

15.15 zipfile  用於讀取ZIP歸檔文件的工具

16 fileinput模塊遍歷一組輸入文件, 每次讀取它們內容的一行, 相似Perl語言中的不帶參數的<>操做.

錯誤和異常(chapter10)

1 常見異常:

1.1 NameError: 嘗試訪問一個未聲明的變量

1.2 ZeroDivisionError: 除數爲0

1.3 StntaxError: python解釋器語法錯誤, 這個異常是惟一一個編譯時錯誤.

1.4 IndexError:  請求的索引超出序列的範圍

1.5 KeyError:  請求一個不存在的字典關鍵字

1.6 IOError: 輸入/出處錯誤

1.7 AttributeError:  嘗試訪問一個未知的對象屬性錯誤

1.8 ValueError:  值錯誤(參數值錯誤)

1.9 TypeError:  類型錯誤(參數類型錯誤)

2 異常的檢測, 抓取處理:

2.1 try ---- except ---- finally

2.2 和java的異常處理相似, 可是這裏不用throws, 只要不顯式的捕獲, 就向上拋出

3 同一個except子句中能夠處理多個異常: except (Exception1[, Exception2, …, Exceptionn])[, reson]:   須要注意的是, except在處理多個異常的時候, 須要把多個異常放在一個元組中.

4 全部異常的基類是Exception, 因此, 能夠使用Exception捕獲全部的異常…固然, 也能夠使用裸except語句捕獲多數的異常

5 異常發生時, 能夠使用sys.exc_info()或獲得當前的系統執行信息, 獲得的結果元組相似下面的格式: (<type 'exceptions.IndexError'>, IndexError('list index out of range',), <traceback object at 0x00C15EE0>)  第一個元素代表異常的類型, 第二個元素是異常, 第三個是堆棧信息

6 有些異常不是因爲錯誤條件引發的, 好比SystemExit, KeyboardInterupt…SystemExit是因爲當前Python應用程序須要退出引發的, KeyboardInterupt則表明用戶按下了ctrl-c, 想要關閉python

7 python2.5以後的異常體系結構

- BaseException

|- KeyboardInterrupt

|- SystemExit

|- Exception

|- (all other current built-in exceptions) 全部當前內建異常

8 異常參數是能夠被忽略的, 其中包含的是對致使異常的代碼的診斷信息, 異常參數一般會自身組成一個元組, 並存儲爲類實例(異常類的實例)的屬性.

9 帶else的try(若是try塊中沒有發生except的異常, 執行else)

try:

     code_block

except (Exception …), reason:

     code_block

else:

     code_block

finally:

     code_block

10 with語句用於上下文管理和資源分配

with context_expression [as var]:

     with_suite

         上面的語句是with的標準語法, 表示經過context_expression表達式建立一個上下文環境, 並將其交給句柄var, 在with_suite中能夠使用這個上下文環境, with會本身去處理上下文環境的準備工做和收尾工做(不管是異常發生仍是執行結束)

11 python2.6開始支持with語法, 支持的模塊有:

11.1 file

11.2 decimal.Context

11.3 thread.LockType

11.4 threading.Lock

11.5 threading.RLock

11.6 threading.Condition

11.7 threading.Semaphore

11.8 threading.BoundedSemaphore

11.9 例如:

with open(‘c:\\1.txt’, ‘r’) as f:

         #file operate

這樣就會自動管理文件的打開關閉等操做和異常處理

12 上下文表達式和上下文管理器(能夠經過自定義本身的類, 實現系統方法__enter__()和__exit__()來定義本身的上下文對象/上下文管理器):

12.1 context_expression 用來得到一個上下文管理器…上下文管理器的職責是提供一個上下文對象.  經過__context__()方法實現, 該方法返回一個上下文對象, 用於在with語句塊中處理細節.   上下文對象自己就能夠是上下文管理器.. 因此context_expression既能夠是一個真正的上下文管理器, 也能夠是一個自我管理的上下文對象, 在後一種狀況時, 上下文對象荏苒有__context__(), 返回其自身.

12.2 得到一個上下文對象以後, 就會調用它的__enter__()方法, 它將完成with語句塊執行前的全部準備工做, with語法中的as後面的句柄, 就是經過__enter__()方法的返回值來賦值的.  若是沒有as子句, 就會丟棄返回值

12.3 執行with語句塊,

12.4 with語句塊執行結束後, 哪怕是因爲異常結束, 都會調用上下文對象的__exit__()方法…  __exit__()方法接受三個參數, 若是with語句塊正常結束, 三個參數所有都是None, 若是發生異常, 獲得的三個參數對應sys.exc_info()獲得的元組的三個元素(類型—異常類, 值—異常實例, 回朔—traceback)

12.5 contextlib模塊中是關於上下文管理的一些實現

13 觸發異常使用raise [SomeException[, args[, traceback]]], 第一項是異常類, 第二項是參數(有多個參數使用元組), 最後一項是回朔信息(堆棧)  

13.1 一般, 錯誤的參數中指出錯誤的緣由子串, 錯誤編號, 錯誤地址等.  也能夠使用raise [exception_instance]

13.2 若是給定的是一個異常實例, 而發生的異常不是該異常類指示的異常, 那麼會根據異常類實例的參數, 從新建立一個實際發生的異常的實例

13.3 raise的語法:

13.3.1 raise exception_class: 觸發一個異常, 從exception_class生成一個實例, 不包含任何異常參數

13.3.2 raise exception_class(): 同上

13.3.3 raise exception_class, args  同上, 可是提供了異常參數, 參數也能夠是一個元組

13.3.4 raise exception_class(args): 同上

13.3.5 raise exception_class, args, traceback  同上, 但提供一個追蹤對象traceback供使用

13.3.6 raise exception_class, instance: 經過實例觸發異常(一般是exception_class的實例):  若是實例是exception_class的子類實例, 那麼這個新異常的類型會是子類的類型. 若是實例既不是exception_class的實例也不是它的子類的實例, 那麼會複製此實例做爲異常參數去生成一個新的exception_class的實例

13.3.7 raise instance: 經過實例觸發異常, 異常類型是實例的類型

13.3.8 raise string:  過期的, 觸發字符串異常

13.3.9 raise string, args: 同上, 但觸發伴隨着args

13.3.10 raise string, args, traceback: 同上, 但提供了一個追蹤對象供使用

13.3.11 raise(python1.5新增): 從新觸發前一個異常, 若是以前沒有發生異常, 觸發TypeError

14 斷言: assert expression[, arguments]  判斷expression表達式, 獲得斷言的真假, 若是真不作任何操做, 若是是假, 觸發AssertionError, arguments是在觸發AssertionError時傳遞給異常的參數.

15 相關模塊:

15.1 exceptions:  內建異常, 不用導入這個模塊

15.2 contextliba:  爲使用with語句的上下文對象工具

15.3 sys  包含各類異常相關的對象和函數(sys.ex*)

函數和函數式編程(chapter11)

1 過程只處理一些操做, 而沒有返回值, 函數則會通過一系列處理返回一些數據. python的過程就是函數

2 關鍵字參數: 調用函數時按照函數定義時指定的形式參數名=實參句柄的方式指定實參值, 這樣的參數就叫關鍵字參數

3 函數屬性不能在函數的聲明中訪問, 由於函數體尚未被建立, 可是當函數體建立完畢以後, 就能夠訪問了.

4 python2.1中引入了內部函數的支持機制, 能夠在一個函數體內直接定義另外一個函數, 內部函數的生命域在父親方法內.

5 函數的裝飾器: 和java中的註解語法一致, 以@開頭, 接下來是裝飾器函數的名字和可選的參數, 接下來是其修飾的函數

@decorator(decorator_option_arguments)

def function2bedecoratedname(func_arguments):

5.1 沒有裝飾器以前, 使用綁定的方式將方法註冊成爲類方法或靜態方法:

5.1.1 object.function = staticmethod(function)  或在類內部直接function = staticmethod(function)

5.1.2 object.function = classmethod(function) 或在類內部直接function = classmethod(function)

5.2 使用裝飾器的語法

5.2.1 靜態方法

@staticmethod

def function():

5.2.2 類方法

@classmethod

def function():

5.2.3 帶參數的裝飾器

@deco1(deco_arg)

@deco2

def func():

就至關於作了

func = deco1(deco_arg)(deco2(func))

5.2.4 裝飾器其實就是函數, 裝飾器接受函數對象, 並對函數對象進行包裝處理, 就至關於java中的aop, 能夠使用裝飾器作一些日誌, 安全性檢查等通用型的功能

def mydecorator(func):

         def wrappedFunc():

                   print ‘log is recorded’

                   return func()

         return wrappedFunc

 

@mydecorator

def f():

         print ‘Hello decorator’

 

print f()

5.2.5 裝飾器的注意點:

5.2.5.1 必須定義一個內部函數名字是wrappedFunc

5.2.5.2 裝飾器函數返回的是內部函數wrappedFunc的引用(或別名)

5.2.5.3 wrappedFunc()函數包裝器所接受的參數就是被裝飾函數的參數列表

5.3 裝飾器能夠有多個, 每行一個, 按照順序寫就能夠了, 其實裝飾器就至關於調用了對應的裝飾器函數, 對於多個裝飾器, 就相似數學上的函數嵌套. (g · f)(x) = g(f(x))

5.4 參數

5.4.1 位置參數, 普通的參數

5.4.2 默認參數, 有默認值的參數

5.4.3 關鍵字參數, 針對調用時, 使用參數名=值的方式調用的

6 使用*和**調用函數

6.1 *, 將用星號指定的實參轉換成一個元組, 元組的每個元素做爲一個參數進行傳遞. 例如a = [1, 2, 3, 4] func(*a)則func接收到了4個參數.

6.2 **, 用兩個星號指定的實參必須是字典類型, 並且字典的鍵必須是str, 這樣傳遞的參數其實是以字典中的數據獲得了N個關鍵字參數

7 可變參

7.1 位置可變參使用*argument_name定義, 函數內部獲得的將是一個元組.

7.2 關鍵字可變參使用**argument_name定義, 函數內部獲得的將是一個字典.

8 匿名函數與lambda: 使用lambda 參數列表: 表達式的方式能夠建立一個匿名函數, lambda構建的函數能夠使用可變參.   優勢在於繞過了函數的棧分配, 性能獲得了提高(測試了10^9數量級次數的空函數調用, 性能提高了1%左右)

9 內建函數

9.1 apply(func[, nkw][, kw]): 用可選的參數來調用func, nkw是非關鍵字參數, kw是關鍵字參數, 返回值就是func調用以後的返回結果

9.2 filter(func, sequence): 調用一個布爾函數func迭代遍歷序列中的每一個元素, 返回一個func返回True的元素的序列.

9.3 map(func, seq1[, seq2…]): 將函數func做用於給定序列中的每一個元素, 並用一個列表來提供返回值, 若是func爲None, func就表現爲身份函數(id), 返回一個含有每一個元素中元素集合的n個元組的列表

9.3.1 提供了多少個seq參數, func就接受多少個參數.

9.3.2 若是func存在, 將各個列表的值按順序傳入到func中, 返回的結果被組成一個新的列表做爲map的返回.

9.3.3 若是func是None, 返回各個列表的相似壓縮獲得的元組的列表, 這裏的壓縮不一樣於zip, 是相似sql中的外聯接的模式.

9.4 reduce(func, seq[, init]): 將二元函數做用於seq序列的元素, 每次攜帶一對(先前的結果以及下一個元素), 連續的將現有的結果和下一個值做用在得到的隨後的結果上, 最後減小序列爲一個單一的返回值, 乳溝初始值init給定, 第一個比較會是init和第一個元素而不是序列的前兩個元素.  有一點相似遞歸調用

10 引入一個模塊的時候能夠起一個別名: from module_name import attribute_name as alias

11 偏函數:  使用functools模塊中的partial()函數建立偏函數, 第一個參數是基函數的引用, 後面跟隨基函數的調用中要使用的一些默認值…這裏還能夠使用關鍵字參數調用的方式:

toDecimal = partial(int, base = 2)

調用的時候, 只須要指定在partial中沒有指定的參數, 好比: toDecimal(‘101010’)

因爲在partial中指定的這些固定的參數是在參數列表的最左邊, 因此, 若是不使用關鍵字參數, 可能會致使參數順序錯誤.

12 在函數體內使用global關鍵字能夠使全局變量的變量名在函數體內得到全局變量的引用, 在函數體內對全局變量的改變會影響全局變量, 例如:

a = 100

def f():

         global a

         a += 300

         print a

獲得的輸出會是400, 而且, 全局變量a也被修改成400

注意: 使用global語法, 必須是在該全局變量名第一次在函數體內被使用以前

13 嵌套函數的內部變量做用域爲本身的函數體(包含本身的內部子孫函數).  在函數體內能夠使用的變量域爲本身的全部父輩中的變量.

14 閉包: 將內部函數本身的代碼和做用於之外的外部函數的做用結合起來, 在一個獨立的做用域中, 多用於安裝計算, 隱藏狀態, 函數對象和做用於中隨意切換, 回調.

14.1 自由變量: 定義在外部函數內(非全局變量), 可是由內部函數引用或者使用的變量.

14.2 閉包: 若是在一個函數內, 對在外部做用域的變量(自由變量)進行引用, 那麼這個內部函數就被認爲是閉包(closure)

14.3 閉包完成的功能很像類.

14.4 閉包將內部函數本身的代碼和做用域之外的外部函數做用結合起來…閉包的詞法變量不屬於全局名字空間域也不屬於局部的, 而是屬於其餘的名字空間, 帶着」流浪」的做用域.  可是, 這又不一樣於對象, 對象的變量存活在對象的名字空間, 而閉包變量存活在一個函數的名字空間和做用域.

14.5 閉包的語法:

14.5.1 定義

def out_function(arg1, arg2, arg3……):  //定義一個外部函數

         args = [arg1, arg2]  //將要做爲自由變量的參數放到一個可變對象中.

         def inner_function(self_arg):  //定義一個內部函數, 這裏能夠接受本身的參數

                   args[0] += args[1] + self_arg  //改變自由變量, 上面將自由變量放到一個可變對象中就是爲了可以保存這種改變.

                   return args[0]  //返回修改後的自由變量值

         return inner_function  //返回內部函數

14.5.2 調用

closure1 = out_function(1, 2, 3)  //獲得一個閉包(調用外部函數, 返回了內部函數的引用, 實際上就造成了一個閉包, 這個閉包的做用域內持有了外部函數內定義的args自由變量和內部函數自己)

closure2 = out_function(4, 5, 6)  //獲得一個閉包

closure1(100)  //調用閉包局部的實參是100

closure2(200)  //調用閉包返回的

14.6 調用閉包返回的結果很相似調用對象的方法, 可是, 閉包是一種可以有本身的獨立做用域的方法, 而對象則是類實例.

14.7 獲得一個閉包的實例(實際上就是一個方法), 查看它的func_closure屬性, 能夠查看該閉包含有的自由變量.

14.8 一個閉包和裝飾器結合的絕妙的例子見python-15-function下的closureAndDecorator4Log.py

14.9 lambda定義的函數做用域, 生命週期和普通函數是一致的, lambda也能夠不指定參數, 也能夠使用全局或外部變量.

14.10 遞歸: 一個超級短的遞歸階乘函數: f = lambda n: n == 1 and 1 or (n == 2 and 2 or n * a(n - 1))

15 生成器: 生成器使用生成器表達式建立, 和列表解析表達式語法相同, 使用圓括號包裹.  也是使用next方法, 完成遍歷以後拋出StopIteration異常.

15.1 定義: 掛起返回出中間值並屢次繼續的協同程序成爲生成器.

15.2 生成器語法:

def mygenerator(arr):

         for i in arr:

                   yield i

15.3 生成器的建立使用了yield語法, 在調用next方法的時候, 返回下一個yield指示的值, 並讓生成器在這個位置停留.

15.4 固然, yield也能夠指示作某一個動做以後中止.  甚至還容許yield指示的動做返回的是一個None

15.5 生成器適用於較大的數據場合.

15.6 生成器的建立函數中不能有return

15.7 生成器還能夠接收外部傳送回來的數據進行交互.  在外部調用生成器的send方法能夠向生成器發送數據, send方法接受一個參數, 這個參數的值就是yield argument_name詞法的返回值.  send方法返回的是通過處理以後到下一次yield的值, 實際上是和調用next()方法的返回值是同樣的, 不過此次是通過了send進來的數據的處理方式.

def counter(start):

     count = start

     while True:

              input = yield count

              if input:

                       count += input

              else:

                       count += 1

模塊(chapter12)

1 影響python的環境變量是PYTHONPATH, 這個是指定python的腳本路徑的環境變量

2 運行時指定python的腳本路徑經過訪問修改sys.path來實現

3 sys.modules可找到當前導入(import)了哪些模塊和它們來自哪些地方, sys.modules是一個字典, 模塊名是key, 物理地址是value

4 名稱空間: 名稱(標識符)到對象的映射

4.1 改變一個名字的綁定叫從新綁定

4.2 刪除一個名字叫作解除綁定

4.3 執行期間有兩個或三個活動的名稱空間, 全局名稱空間和內建名稱空間是固有的, 局部名稱空間是不斷變化的. 

4.4 從名稱空間訪問名字依賴於它們的加載順序

4.5 python解釋器首先加載內建名稱空間. 內建名稱空間由__builtins__模塊中的名字構成. 而後加載全局名稱空間, 在模塊開始執行後變成活動名稱空間…… 此時, 咱們就有了兩個活動的名稱空間.  若是在運行期間調用了一個函數, 就建立出第三個名稱空間, 也就是局部名稱空間.  也能夠使用globals()和locals()內建函數判斷出某一個名字屬於那個名稱空間

4.6 名稱空間和變量做用域:

 

4.7 無限空間: 指定一個名字以後, 若是名字指向的是一個名字空間, 均可以使用.語法爲其添加屬性

5 導入模塊的順序:  使用空行分割三種不一樣類型的導入

5.1 python標準庫

5.2 python第三方庫

5.3 python應用程序自定義模塊

6 from module import name1, name2…

7 from module import name1 as alias1, name2 as alias2

8 執行import語句進行導入的時候, 被導入的模塊的頂層代碼將會被執行, 而且, 這種執行只有一次(該模塊在整個python程序進程或pythonVM中第一次被導入時)

9 將已經安裝的模塊做爲腳本執行, 使用[$ foo.py]

10 from-import導入方式並非良好的編程風格, 這會污染當前名稱空間

11 from __future__ import new_feature 是用來導入python的新特性的, 必須使用from-import的方式.

12 警告框架: Warning直接從Exception繼承, 是全部警告的基類: UserWarning, DeprecationWarning, SyntaxWarning, RuntimeWarning

13 能夠從指定zip文件名到sys.path, 從zip文件中直接導入模塊

14 *新的導入鉤子:

14.1 查找器: 接受一個參數: 模塊或包的全名, 查找器實例負責查找模塊

14.2 載入器: 若是查找器查找成功將會返回一個載入器對象.  載入器會將模塊載入到內存.

14.3 查找器和載入器實例被加入到sys.path_hooks

14.4 sys.path_importer_cache用來保存這些實例.

14.5 sys.meta_path用來保存一列須要在查詢sys.path以前訪問的實例

15 模塊內建函數:

15.1 __import__(): python1.5加入這個函數, 是實際上的導入模塊函數. __import__()函數的語法是: __import__(module_name[, globals[, locals[, fromlist]]])  其中module_name是要導入的模塊的名稱, globals是包含當前全局符號表的名字的字典, locals是包含局部符號表的名字的字典, fromlist是一個使用from-import語句所導入符號的列表…….globals, locals和fromlist默認是globals(), locals(), []

15.2 globals()和locals(), 返回調用者的全局和局部名稱空間的字典.

15.3 在全局空間下使用locals()和使用globals()獲得的結果是同樣的, 由於此時的局部名稱空間就是全局名稱空間.

15.4 reload(module_name)內建函數能夠從新導入一個已經導入的模塊(從新加載運行一次該模塊)  使用reload()從新加載的模塊必須是以前被所有導入的模塊, 而不能是from-import導入的模塊, 也就是說在全局名稱空間中必需要有這個模塊

16 包

16.1 解決的問題

16.1.1 爲平坦的名稱空間加入了有層次的組織機構

16.1.2 容許程序員把有聯繫的模塊組合到一塊兒

16.1.3 容許分發者使用目錄結構而不是一大堆混亂的文件

16.1.4 幫助解決有衝突的模塊名稱.

16.2 使用了包以後的導入語法和modle是一致的.

16.3 包內須要有一個__init__.py文件, 用來指示初始化模塊.  使用from-import語句導入子包的時候須要用到它, 若是沒有用到, __init__.py能夠是空文件.  若是包內沒有__init__.py, 那麼會致使一個ImportWarning信息…… 可是, 除非給解釋器傳遞了-Wd選項, 不然, 該警告會被簡單的忽略.

16.4 __init__.py文件中經過指定__all__變量(模塊名稱字符串組成的列表)指定使用from-import *方式導入的時候, 導入包內的哪些模塊

16.5 絕對導入: 如今的全部導入都被認爲是絕對的, 也就是說這些名字必須經過python路徑(sys.path或環境變量PYTHONPATH)來訪問…. 絕對導入就是指直接使用import語句導入, 此時, 就必須指定能夠經過python路徑訪問到的腳本

16.6 相對導入: from-import導入, 相對包和模塊而言.例如

16.6.1 from Phone.Mobile.Analog import dial

16.6.2 from .Analog import dial

16.6.3 from ..common_util import setup

16.6.4 from ..Fax import G3.dial

17 sys.modules是一個列表, 包含了一個由當前載入(完整而且成功導入)到解釋器的模塊組成的字典. 模塊名是鍵, 位置是值

18 *阻止屬性導入: 若是不想讓某個模塊屬性被from module_name import *導入, 能夠給不想導入的屬性名稱加上一個下劃線.  也就是說_開頭的模塊是包內私有的, 不被外部導入.   可是, 若是使用顯式的調用(例如import module_name._private_attribute)導入, 那麼這個隱藏就會失效.

19 加入PYTHONCASEOK的環境變量, 就會使python導入模塊的時候不區分大小寫.

20 python2.3開始, 模塊文件開始支持除7位ASCII以外的其餘編碼, 可是ASCII是默認的, 想要使模塊文件支持其餘編碼, 必須在python模塊頭部加入一個額外的編碼指示說明, 這樣就可讓導入者使用指定的編碼解析模塊, 編碼對應的Unicode字符串.  例如, UTF-8的編碼的文件能夠這樣指示:

# -*- coding: UTF-8 -*-

這樣,

21 導入循環問題: A模塊加載須要導入B模塊, B模塊加載須要導入A模塊,  解決方案: 在循環的其中一個節點,  將依賴模塊的導入分解到各個須要的方法中(也就是將導入局部化, 放到局部名稱空間中.)

22 模塊執行: 使用命令行, 或者在運行時調用execfile(filename[, globals_dict[, locals_dict]])函數  若是不指定globals_dict和locals_dict默認是當前的globals()和locals()

23 相關模塊

23.1 imp  提供一些底層的導入者功能

23.2 modulefinder  容許查找python腳本所使用的全部模塊, 能夠使用其中的ModuleFinder類或是把它做爲一個腳本執行, 提供本身要分析的另外一個python模塊的文件名

23.3 pkgutil  提供了多種把python包打包成一個」包」文件進行分發的方法, 相似site模塊, 使用*.pkg文件幫助定義包的路徑, 相似site模塊的*.pth文件

23.4 site和*.pth文件配合使用, 指定包加入python路徑的順序, 例如: sys.path, PYTHONPATH, 不須要顯式的導入它, 由於python導入時默認已經使用該模塊,   能夠使用解釋器參數-S開關在python啓動時關閉它.

23.5 zipiimport   能夠使用該模塊導入zip歸檔文件中的模塊

23.6 distutils   提供了對創建, 安裝, 分發python模塊和包的支持, 能夠幫助創建使用C/C++完成python擴展.

23.7 importAs()函數提供了from-import-as的語法支持   python2.6中已經被廢棄???或者再也不標準內建庫中..

面向對象編程(chapter13)

1 新式類必須繼承至少一個父類, 類定義時的參數bases能夠是一個(單繼承)或多個(多重繼承)用於繼承的父類

2 object是全部類的基類, 若是定義類的時候沒有定義bases參數, 若是沒有指定父類, 那麼建立的就是一個經典類.

3 類中的方法必須至少有一個參數, 這個參數就是用來傳遞調用的實例的.

4 調用靜態方法的時候, 不會傳入調用者自身, 而調用類方法或者unbound的方法的時候就會自動的傳入調用者自身, 所以, 類方法和unbound方法必須有至少一個參數.

5 __init__方法相似於類構造器, python在建立實例後, 在實例化過程當中, 調用__init__方法,

6 python中的類繼承結構是單層的, 也就是說若是子類覆寫了父類的構造方法, 那麼父類的構造方法將不會被自動調用, 那麼, 其實你也能夠手動的調用父類的構造方法, 然而, 這就跟調用普通的方法沒有什麼區別了, 而不像是java中, 每一個子類實例其實都持有了父類實例的引用, 這樣就能夠方便的關聯操做.

7 命名規則, 駝峯標記法+下劃線方式.

8 OOD是不要求實現語言的, 也能夠使用非OO語言實現OOD設計.

9 抽象: 對現實世界問題和實體的本質表現, 行爲和特徵的建模, 創建一個相關的子集, 能夠用來描繪程序結構, 從而實現這種模型.  抽象包括數據屬性和數據接口.

10 封裝/接口: 描述了對數據/信息進行隱藏的觀念, 它對數據屬性提供接口和訪問函數.   可是, 在python中, 全部的類屬性都是公開的.

11 合成: 擴充了對類的描述, 使得多個不一樣的類能夠合成一個更大的類.

12 派生/繼承/繼承結構: 派生描述了子類的建立, 新類保留已存類類型中全部須要的數據和行爲, 但容許修改或者其餘的自定義操做, 都不會修改原類的定義.

13 多態: 泛化的定義, 獲得特化的實現.  容許使用泛化的共同接口操做.

14 自省/反射: 跟java的反射是一個道理???

15 python中不支持抽象方法(C++中成爲純虛函數), 能夠使用在方法中引起NotImplementedError異常得到相似的效果.

16 python中的類屬性就至關於靜態屬性.

17 python類中的方法必須進行綁定, 雖然不少時候, 未綁定的方法也可以調用成功, 可是, python不保證未綁定方法必定調用成功.  並且, 不管是否進行綁定, 在類中定義了的方法都是所在類的固有屬性.

18 globals()和locals()中的名稱都是在對象被裝載的時候進行加載的, 因此, 只要在調用完成了裝載, 那麼locals()和globals()中的名稱就都是能夠用的, 除非對其進行卸載.

19 類的屬性:

19.1 dir()返回對象的屬性的名字列表.

19.2 __dict__返回對象的屬性的key-value字典, 可是, __dict__獲得的屬性不如dir()獲得的多, 另外, 使用vars(class_name)內建函數一樣能夠獲得__dict__屬性中的內容, 可是, 這裏vars()函數返回的應該是__dict__的一個拷貝(深淺不知), 而不是源對象.   __dict__中基本上只包含咱們自定義的屬性.

19.3 特殊的類屬性

19.3.1 __name__  類的名字

19.3.2 __doc__  類的文檔字符串….文檔屬性不能被派生類繼承

19.3.3 __bases__  類的全部基類組成的元組

19.3.4 __dict__  類中的屬性的key-value字典

19.3.5 __module__  類定義所在的模塊

19.3.6 __class__  實例對應的類.(僅在新式類中)

20 經典類本質上是一個類對象, 注意, 這裏是對象, 而新式類是一種類型的定義, 經過調用repr(class_name)能夠明確的發現, 經典類返回的是<class module_name.class_name at 0x00B98CC0>, 而新式類返回的是<class ‘module_name.class_name’>, 經過調用type(class_name) 也能夠看到, 經典類返回的是<type ‘classobj’>, 而新式類返回的是<type ‘type’>, 也就是說, 新式類將class和type進行了統一.

21 若是在一個類定義中兩次使用了同一個名稱, 那麼後面定義的名稱會覆蓋前面定義的名稱.

22 經典類的實例用type函數獲得的是<type ‘instance’>而不會指定具體是哪個類的實例

23 __init__, 僞構造器

23.1 不用經過new建立實例, python的類型沒有構造器

23.2 __init__()方法只是在解釋器建立一個實例以後調用的第一個方法.

24 __new__, 更接近構造器的僞構造器

24.1 __new__是在python2.2時爲了使用戶能夠對內建類型進行派生, 而誕生的一種實例化不可變對象的途徑.

24.2 __new__()接受的第一個參數就是類自己

24.3 __new__()是一個類方法, 傳入的參數是在類實例化操做以前生成的,

24.4 __new__()會調用父類的__new__()來建立對象(向上代理)

24.5 __new__()方法必須返回一個合法的實例

24.6 在__new__()方法中能夠調用父類的__new__()方法建立對象…….

25 __new__和__init__對比

25.1 __new__接受的第一個參數是類型, 而__init__接受的第一個參數是實例

25.2 __new__方法中, 能夠調用父類的__new__方法, 第一個參數傳遞本身的__new__方法中接受的第一個參數. 這樣, 父類的__new__方法就能夠構建出一個新的對象.

25.3 __new__方法中創造了實例對象(至少看起來是這樣的, 其實是父類的__new__建立, 歸根結底, python仍是沒有把這個工做交給咱們), 並將它返回.

25.4 __new__返回的實例對象, 就是__init__方法接受的第一個參數.

25.5 __new__和__init__方法雖然第一個參數的類型和意義不同, 可是, 除了第一個參數,他們接受的參數都是必須同樣的, 就是調用構造的時候傳遞的參數.

26 __del__解構器:

26.1 解構器在一個實例的全部引用都被清除後才被調用的, 好比, 當引用計數已經減小到0

26.2 一個對象的生命週期中, 解構器只能被調用一次

26.3 解構器使用的注意點:

26.3.1 首先調用父類的解構器__del__()

26.3.2 調用del x不表示調用了x.__del__()

26.3.3 若是有一個循環引用或其餘緣由, 讓一個實例的引用一直存在, 那麼__del__永遠不被調用

26.3.4 __del__()未捕獲的異常會被忽略.(由於__del__過程當中可能有些變量已經被刪除了)

26.3.5 若是不知道爲何, 就不要實現__del__

27 能夠經過結合__init__和__del__的方式, 使用靜態變量記錄一個類具體有多少個實例等相關信息.

28 構造器中設置默認參數的時候, 應該設置的是不可變對象, 向列表, 字典這樣的可變對象能夠扮演靜態數據. 而後在每一個方法調用中維護它們的內容.

29 __init__方法不能返回None以外的任何類型.

30 特殊的實例屬性:

30.1 __class__  實例的類型

30.2 __dict__  實例屬性的字典集合

31 內建類型中不存在__dict__這個屬性

32 不管在哪裏使用類屬性, 都要加類名前綴

33 類屬性的值只有在使用類調用的時候, 才能夠更新, 若是使用實例名稱訪問類屬性, 視圖修改的……給實例賦一個同名變量, 就能夠隱藏類中的變量.

34 方法就是類內部定義的函數. 方法只有在其所屬的類擁有實例時, 才能被調用, 當存在一個實例的時候, 方法就被認爲綁定到那個實例了. 沒有實例時的方法就是未綁定的.

35 方法縱覽:

35.1 未綁定方法: 直接定義的方法, 而且調用的時候使用類調用而不是實例調用

35.2 實例方法: 直接定義的方法, 使用實例調用, 在建立實例時, 被自動綁定到了實例名稱空間彙總

35.3 靜態方法: 使用@staticmethod定義或使用staticmethod()內建函數綁定的方法, 使用類和實例調用都不會傳遞默認參數

35.4 類方法: 使用@classmethod定義或使用classmethod()內建函數綁定的方法, 無論使用類或實例調用, 默認都會傳遞第一個參數, 這個參數的值是當前調用的類自己, 或實例所屬的類

36 __bases__用來獲取類的基類

37 python中繞過多態能夠以未綁定方式直接調用父類的方法, 將子類實例做爲第一個參數傳入

38 內建函數super(type, object | sub_type) 用來獲取一個僞的父類引用.

39 若是__init__()方法被子類重寫, 那麼, 在建立子類的實例的時候, 就不會在自動的調用父類的__init__方法.  若是須要, 就要手動的去調用

40 經過繼承擴展標準類型(新式類)

40.1 不可變類型: 經過重寫__new__方法實現. 在__new__中能夠return super(class_name, first_argument).__new__(arguments)來返回一個實例

40.2 可變類型: 須要修改什麼行爲, 就修改什麼行爲.

41 多重繼承中的方法解析順序

 

41.1 經典類採用了深度優先, 從左到右的算法.  這種算法存在的問題是: 可能因爲多重繼承致使實際調用的方法不是最’親’的祖先中定義的方法.  如上圖, 則GC中的實例調用bar方法實際會調用p2的bar, 而不是c2.

41.2 新式類採用了廣度優先, 從左到右的算法. 有效的解決了從繼承樹中獲得的方法不是最’親’的祖先的方法的問題. 

41.3 新式類中加入了新的屬性__mro__, 該屬性是一個元組, __mro__就標識了新式類中繼承樹結構中的名稱搜索順序.

41.4 mro和菱形繼承結構: 以下圖, 就發生了菱形繼承結構, 類D的名稱查找過程可能會兩次回朔到菱形的上頂點.

 

42 issubclass(sub_class, super_class | tuple_of_superclasses) 判斷一個類是另外一個類的子類或子孫類.  python2.3開始, 第二個參數支持祖先類的元組方式.

43 isinstance(obj1, obj2) 判斷類obj1是類obj2的一個實例或者是obj2的一個子孫類的實例, 第二個參數應該是一個類.

44 hasattr(object, name), getattr(object, name[, default]), setattr(object, name, value), delattr(object, name)能夠在各類對象下工做, 用以操做對象的屬性.

45 dir

45.1 做用在實例上: 顯示實例變量和所在類, 以及全部基類中的方法和類屬性

45.2 做用在類上: 顯示類以及它的全部基類的__dict__中的內容, 但不會顯示定義在元類中的類屬性

45.3 做用在模塊上, 顯示模塊的__dict__內容

45.4 不帶參數時, 顯示調用者的局部變量

46 super()內建函數返回的是super類的實例對象, 主要被用來查找父類中的屬性.

47 super(type, obj=None) 返回一個表示父類類型的代理對象; 若是沒有傳入obj, 則返回的super對象是非綁定的, 反之, 若是obj是一個type, issubclass(obj, type)就必然是True, 不然 isinstance(obj, type)就必然爲True

48 dir(obj=None)  返回obj的屬性的一個列表, 若是沒有給定obj, dir()返回的是當前局部名字空間中的屬性, 也就是locals().keys()

49 vars(obj=None)  返回obj的屬性及其值的一個字典, 若是沒有給出obj, vars()顯示局部名字空間字典(屬性及其值), 也就是locals()

50 用特殊方法定製類, python中支持經過一些特殊的方法的重寫, 實現將類模擬成標準類型或對運算符進行重載, 能夠使用的特殊方法見python核心編程表13.4

51 在python中, 能夠使用assert condition, ‘msg’的方式斷言.

52 若是要使__str__()和__repr__()作一樣的輸出, 那麼不妨實現其中的一個方法, 而將另外一個方法做爲那個實現了的方法的別名, __repr__ = __str__

53 在類中, 使用本類的構造器, 直接使用self.__class__()

54 使用__iter__方法和next能夠重載使得對象支持迭代器, 在__iter__方法中, 咱們只須要將self返回就能夠了

55 私有化

55.1 雙下劃線: 類中雙下劃線開始的屬性, 在運行時會被混淆, 不容許直接訪問, 混淆的機制是採用了self._classname__attributename的方式, 第一個是但下劃線, 第二個是雙下劃線.  這樣作的目的在於保護屬性不至於因爲和父類名字空間衝突致使父類的同名屬性被隱藏.

55.2 但下劃線: 在模塊內部, 若是一個屬性以單下劃線開始, 那麼, 該屬性將不會被其餘模塊的from-import *引用到, 可是, 對於import則會跳過這個隱藏.

56 包裝和受權

56.1 包裝是指對一個已經存在的對象進行包裝, 無論它是數據類型仍是一段代碼.  能夠是對一個已經存在的對象, 增長新的, 刪除不要的, 或者修改其餘已經存在的功能.

56.2 受權是包裝的一個特性, 用於簡化處理有關dictating功能, 採用已經存在的功能以達到最大限度的代碼重用.

56.3 實現受權的關鍵在於覆蓋__getattr__(self, attr_name)方法, 在代碼中, 經過調用內建函數getattr(object, attr_name)來獲取對象的指定屬性.

56.4 當引用一個屬性的時候, python解釋器將首先在局部名稱空間查找那個名字, 而後搜索類名稱空間, 以防一個類屬性被訪問, 最後, 若是兩類搜索都失敗了, 搜索則對源對象開始受權請求, 此時, __getattr__()方法將會被調用

56.5 使用受權, 僅僅能對屬性進行受權, 特殊的行爲, 好比list的切片操做, 在包裝後通過受權也是不能使用的.  緣由是切片操做其實是調用了__getitem__()方法, 且__getitem__()方法沒有做爲一個類實例方法進行定義.

57 __slots__類屬性:

57.1 因爲字典__dict__屬性跟蹤全部實例屬性, 所以, 字典會佔據大量內存, 當一個類有不少實例的時候, 就會帶來內存的壓力, 如今能夠使用__slots__屬性來代替__dict__

57.2 __slots__是一個類變量, 由一個序列型對象組成, 由全部合法標識構成的實例屬性的集合來表示, 能夠是一個列表, 元組或可迭代對象. 也能夠是標識實例能擁有的惟一的屬性的簡單字符串.   任何在實例中試圖建立__slots__中的名字的實例屬性都將致使AttributeError異常.

57.3 __slots__的目的是節約內存, 可是, 卻限制了用戶自由的爲實例添加動態屬性.

57.4 帶__slots__屬性的類定義不會存在__dict__了, 除非在__slots__中增長__dict__元素

58 __getattribute__()被重寫以後, 除非明確從__getattribute__()調用, 或__getattribute__()引起了AttributeError異常, 不然, __getattr__不會被調用.

59 __getattr__和__getattribute__兩個系統方法比較

59.1 __getattr__方法只有在搜索完類名稱空間, 實例名稱空間沒有發現變量的時候, 纔會被調用

59.2 __getattribute__若是定義了, 則只使用__getattribute__方法進行搜索變量

59.3 getattr(object, attribute_name)內建函數實際上就是調用了object的__getattr__或__getattribute__方法(若是定義了 __getattribute__就不會調用__getattr__), 因此, 在__getattr__或__getattribute__中使用getattr內建函數的時候須要注意, 當該方法沒有返回合適的變量的時候, 就會帶來無限循環的問題

60 描述符: 表示對象屬性的一個代理

60.1 描述符就至關於一個類屬性(對象)的一個代理, 這個代理實現了__get__(self, obj, type=None), __set__(self, obj, value)和__delete__(self, obj), 三個方法.  當試圖訪問, 修改或刪除該對象指示的屬性的時候, 實際上就會調用這三個方法進行處理

60.1.1 __get__(self, obj, type = None), 當使用描述符名稱訪問的對象的時候, 會調用該方法, self表明描述符對象本身, obj就是當前要訪問該描述符的類實例

60.1.2 __set__(self, obj, value), 當使用描述符名稱設置對象值的時候, 會調用該方法, self表明描述符對象本身, obj就是當前要持有描述符的類實例, value就是要設置的值

60.1.3 __delete__(self, obj) 刪除描述符指定的名稱的時候, 調用該方法, 參數意義同上

60.2 代碼描述:

'''

Created on 2009-9-29

 

@author : selfimpr

'''

class Window(object):

    def __init__(self, width, height):

        self.width = width

        self.height = height

 

class WindowDescriptor(object):

    def __init__(self, obj):

        self.data = obj

    '''

    @param self: instance of WindowDescriptor

    @param obj: instance of Main

    @param type: unknow

    '''

    def __get__(self, obj, type = None):

        print 'get method called'

        return 'width: %s, height: %s' % (self.data.width, self.data.height)

    '''

    @param self: instance of WindowDescriptor

    @param obj: instance of Main

    @param value: value is 1024, it is the value after equal mark

    '''

    def __set__(self, obj, value):

        print 'set method called'

        self.data.width = value

        self.data.height = obj.height

    '''

    @param self: instance of WindowDescriptor

    @param obj: instance of Main

    '''

    def __delete__(self, obj):

        print 'delete method called'

        del self.data

        del self

 

class Main(object):

    def __init__(self, height):

        self.height = height

    '''

    This is a data descriptor

    '''

    window = WindowDescriptor(Window(width = 800, height = 600))

 

 

if __name__ == '__main__':

    m = Main(600)

    m.height = 768

    m.window = 1024 #call method name is __set__ in window data descriptor

    print m.window #call method name is __get__ in window data descriptor

del m.window #call method name is __delete__ in window data descriptor

60.3 以上面代碼爲例, m.window實際上就調用了WindowDescriptor的__get__()方法, 這其實就相似於Main.__dict__[‘window’].__get__(obj, Main)

60.4 優先級別:  在一個類中, 全部的屬性有如下集中, 使用屬性名稱訪問的時候, 它們的優先級順序以下.

60.4.1 類屬性

60.4.2 數據描述符

60.4.3 實例屬性

60.4.4 非數據描述符(方法)

60.4.5 默認爲__getattr__方法

60.5 inspect(檢查)模塊提供了對於屬性類型的檢查: isdataDescriptor(obj)檢查一個對象是不是一個數據描述符

60.6 任何函數(普通的函數, 靜態方法, 類方法, 實例方法等)都是描述符, 函數本身的__get__方法用來處理調用對象, 並將調用對象返回給程序員.

61 屬性和property()內建函數: 對於一些數據屬性, 咱們能夠採用預約義一些方法來提供其操做接口, 將這些預約義的方法設置成隱藏的, 數據自己是不可見的且只讀的(使用雙下劃線定義爲隱藏), 而後, 經過一個公共的接口, 使用property(get_func = None, set_func = None, del_func = None, doc = None)公開其訪問權限, 例以下面代碼(下面代碼中改造的是實例屬性, 能夠使用一樣的方法改造類屬性):

class a(object):

    def __init__(self, width):

        self.__width = ~width

    def getWidth(self):

        return ~self.__width

    def setWidth(self, width):

        self.__width = ~width

        print 'now, width is: %s' % ~self.__width

    def delWidth(self):

        self.__width = ~-1

        print 'now, width is: %s' % ~self.__width

    width = property(getWidth, setWidth, delWidth)

 

if __name__ == '__main__':

    aa = a(1000)

    print aa.width

    aa.width = 30

    del aa.width

62 對於上面的屬性使用property的改進

62.1 ‘借用’一個函數的名字空間

62.2 編寫一個用做內部函數的方法做爲property()的參數

62.3 (用locals())返回一個包含全部的函數/方法名和對應對象的字典

62.4 把字典傳入property()

62.5 去掉臨時的名字空間

63 使用裝飾器的方式解決上面的問題: 該問題其實是爲了解決因爲屬性私有化以後須要提供多個操做接口致使的類名稱空間龐雜的問題

class a(object):

    def __init__(self, width):

        self.__width = ~width

    @property

    def width(self):

        return ~self.__width

    @width.setter

    def width(self, width):

        self.__width = ~width

        print 'now, width is: %s' % ~self.__width

    @width.deleter

    def width(self):

        self.__width = ~-1

        print 'now, width is: %s' % ~self.__width

 

if __name__ == '__main__':

    aa = a(1000)

    print dir(a)

    print aa.width

    aa.width = 30

    del aa.width

64 元類(Metaclasses): 用來定義某些類是如何被建立的, 默認使用的元類是type, 元類就是類的類

64.1 建立一個類的時候, 解釋器須要知道這個類的正確的元類, 解釋器首先尋找雷屬性__metaclass__, 若是屬性不存在, 繼續查找繼承樹中類的__metaclass__屬性, 若是仍是沒有發現該屬性, 就會檢查名字爲__metaclass__的全局變量, 若是都沒有查找到, 那麼這個類就是一個傳統類, 使用types.ClassType做爲此類的元類.

64.2 若是在一個傳統類中設置了__metaclass__=type  那麼這個傳統類就升級爲新式類

64.3 元類的__init__方法接受四個參數, class類, name屬性名, bases基類元組, attrd屬性字典

64.4 元類使用示例:

class MyMetaClass(type):

    def __init__(cls, name, bases, attrd):

        print cls, name, bases, attrd

        super(MyMetaClass, cls).__init__(name, bases, attrd)

        if '__str__' not in attrd:

            raise TypeError, 'Must rewrite __str__ method'

class Class(object):

    __metaclass__ = MyMetaClass

    pass

 

if __name__ == '__main__':

Class()

65 相關模塊和文檔:

65.1 inspect: 提供一些經常使用的判斷, 好比判斷一個名稱是不是數據描述符等

65.2 types: python類型庫

65.3 operator: 標準操做符的函數版本庫

65.4 UserList: 提供一個列表對象的封裝類

65.5 UserDict: 提供一個字典對象的封裝類

65.6 UserString: 提供一個字符串對象的封裝類; 又包括一個MutableString子類

執行環境(chapter14)

1 Python中的執行場景:

1.1 在當前腳本繼續執行

1.2 建立和管理子進程

1.3 執行外部命令或程序

1.4 執行須要輸入的命令

1.5 經過網絡來調用命令

1.6 執行命令來建立須要處理的輸出

1.7 執行其餘的python腳本

1.8 執行一系列動態生成的python語句

1.9 導入python模塊(同時執行它的頂層代碼)

2 可調用對象: 任何能經過函數調用操做符」()」進行調用的對象.

2.1 apply(object[, args[, kargs]]): object必須是一個可調用對象(實現了__call__()方法), 該方法是用來動態調用object這個可調用對象, 使用方法中傳入的其餘參數.  返回的就是object被調用以後的返回值.

2.2 filter(function or None, sequence): 對sequence的每一個元素調用function, 若是返回True, 則將元素過濾掉, 返回的是過濾以後的list

2.3 map(function, sequence[, sequence, …])將全部被傳入的全部序列遍歷, 應用指定的function返回值做爲新的list的元素, 生成的新的list是返回值.

2.4 reduce(function, sequence[, initial]): 將序列進行遍歷, function接受兩個參數, 分別爲遍歷的當前元素和下一個元素, 進行處理, 返回的值做爲新的list的元素, 若是指定initial, 在遍歷元素以前, 會有一個初始值.  生成的新的list會做爲返回值返回.

3 python有四種可調用對象: 函數, 方法, 類, 一些類的實例.

4 函數: python有三種不一樣類型的函數對象: 內建函數, 用戶自定義函數, 方法(方法又分爲內建方法和用戶自定義方法兩種)

4.1 內建函數: 用c/c++實現, 編譯後放入python解釋器, 做爲內建名稱空間的一部分加載進系統., 在_builtin_模塊中, 在python中, 默認將該模塊做爲__builtins__模塊導入.

4.1.1 內建函數屬性:

4.1.1.1 __doc__  文檔字符串

4.1.1.2 __name__  字符串類型的文檔名字

4.1.1.3 __self__  設置爲None, 保留給built-in方法(對比內建方法的__self__屬性, 就能夠看出不一樣之處)

4.1.1.4 __module__  存放bif定義的模塊名字

4.1.2 因爲內建函數和內建方法的內部實現機制都是相同的, 因此, 對內建函數和內建方法調用type獲得的結果相同, 都是: <type ‘builtin_fuction_or_method’>, 內建的工廠函數調用type則會返回<type ‘type’>

4.2 用戶定義的函數: 一般是python寫的, 定義在模塊的最高級, 做爲全局名字空間的一部分.

4.2.1 用戶定義的函數的屬性:

4.2.1.1 __doc__  文檔字符串, 也能夠使用func_doc獲取

4.2.1.2 __name__  字符串類型的函數名稱¸ 也能夠使用func_name獲取

4.2.1.3 func_code  字節編譯的代碼對象

4.2.1.4 func_defaults  默認的參數元組

4.2.1.5 func_dict  函數屬性的名字空間

4.2.1.6 func_globals  全局名字空間, 和從函數中調用globals同樣

4.2.1.7 func_closure  包含了自由變量的引用的單元對象元組.(閉包)

4.2.2 從實現上來看, 用戶定義函數是’函數’類型的, 所以, type調用的時候, 返回的是<type ‘function’>

4.2.3 lambda表達式建立的匿名函數的函數名是lambda, 經過調用func_name或__name__能夠獲取.

4.3 內建方法: 內建類型中定義的方法.

4.3.1 內建方法的屬性:

4.3.1.1 __doc__  文檔字串

4.3.1.2 __name__  字符串類型的函數名字

4.3.1.3 __self__  綁定的對象

4.3.2 內建方法和內建函數的不一樣在於他們的__self__屬性指向不一樣, 內建函數的__self__指向None¸ 而內建方法的__self__指向的是調用它的對象.

4.4 用戶定義的方法: 包含在類定義中, 僅有定義它們的類的實例能夠調用, 若是在子類中該方法沒有被覆蓋, 那麼也能夠被子類實例調用, 用戶定義方法是和類對象關聯的(非綁定方法), 可是隻能經過類的實例進行調用(綁定方法)…….不管用戶定義方法是否綁定, 都是相同的類型」實例方法」, 使用type獲得的結果是<type ‘instancemethod’>

4.4.1 用戶定義方法的屬性:

4.4.1.1 __doc__  文檔字符串

4.4.1.2 __name__  字符串類型的方法名稱, 與im_func.__name__相同

4.4.1.3 __module__  定義該方法的模塊的名稱

4.4.1.4 im_class  對於綁定的方法來講, 是方法相關聯的類, 對於非綁定的方法, 是要求用戶定義方法的類

4.4.1.5 im_func  方法的函數對象

4.4.1.6 im_self  若是是綁定方法, 就是相關聯的實例, 若是是非綁定方法, 就是None

5 可調用對象, 實現__call__方法的類的實例能夠做爲可調用對象.

6 代碼對象, 代碼對象返回的是該對象被編譯成字節的代碼, 調用eval(f.func_code)就至關於調用了f()

7 可執行的對象聲明和內建函數:

7.1 callable(), 是一個布爾函數, 肯定一個對象是否能夠經過函數操做符’()’進行調用

7.2 compile(source, filename, mode[, flags[, dont_inherit]]), 容許程序員在運行時迅速生成代碼對象, 而後就能夠使用exec語句或內建函數eval()執行這些對象或對它們進行求值.

7.2.1 source: 要動態編譯的代碼字符串

7.2.2 filename: 存放代碼對象的文件的名字

7.2.3 mode: 值爲eval(可求值的表達式, 和eval()一塊兒使用) | single(單一可執行語句, 和exec一塊兒使用) | exec(可執行語句組, 和exec一塊兒使用)

7.3 eval(source[, globals[, locals]]): 對錶達式求值, source是字符串或預編譯代碼對象. globals必須是字典, 是source的全局名稱空間. locals能夠是任意的映射對象(實現了__getitem__()方法的對象), globals和locals默認是globals()和locals()返回的值.  若是隻傳入了globals參數, 那麼該字典也會做爲locals傳入.

7.4 exec obj: 能夠執行代碼對象或者字符串形式的python代碼, 一樣, 使用compile()預編譯重複代碼有助於改善性能.  exec也能夠接受有效的python文件對象. 在執行文件對象的時候, 只能執行一次有效, 是由於文件讀取完畢, 指針就會指向文件末尾, 能夠使用file.seek(0)方法把文件的指針從新指向文件頭.

7.5 input(string): input實際上就是eval(raw_input(string)), 獲取一個字符串對該字符串執行動態求值.

8 execfile(filename[, globals = globals()[, locals = locals()]]) 使用傳入的globals和locals名稱空間執行一個python腳本文件.  若是不指定名稱空間, 使用當前的名稱空間.

9 python –c  -m開關

10 執行其餘程序(os模塊):

10.1 system(cmd): 執行命令行程序, 接受字符串的參數. 等待程序結束, 返回退出代碼(windows下始終返回0)

10.1.1 約定使用返回狀態0表示執行成功, 非0表示其餘類型的錯誤.

10.2 fork() 建立一個和父進程並行的子進程(一般來講和exec*()一塊兒使用), 返回兩次…… 一次給父進程, 一次給子進程…… 子進程獲得的返回是0, 父進程獲得的返回是父進程的pid…  能夠經過斷定fork()的返回值的方式, 讓兩個進程執行不一樣的動做…兩個進程是交互得到CPU時間片的. 能夠經過下面的程序看出兩個進程的交互執行的過程:

def f():

      r = os.fork()

      if r == 0:

               for i in range(100):

                        print ‘child:%d’ % i

               print ‘child process end’

      else:

               for i in range(100):

                        print ‘parent:%d’ % i

               print ‘parent process end’

10.3 execl(file, *args) 以args指定的參數模式運行可執行文件. 替換當前進程….

10.4 execv(file, args) 經過元素是字符串的列表或元組執行可執行文件, 並替換當前進程.   這裏使用了參數向量列表

10.5 execle(file, arg0, arg1, …, env)  和execl相同, 但提供了環境變量字典env

10.6 execve(file, arglist, env)  arglist是元素爲字符串的列表或元組表示的向量參數列表., env是要使用的環境變量.

10.7 execlp(cmd, arg0, arg1, …)和execl()相同, 可是在用戶的搜索路徑下搜索徹底的文件路徑

10.8 execvp(cmd, arglist)  除了帶有參數向量列表 和execlp()相同.

10.9 execlpe(cmd, arg0, arg1, …, env) 執行外部程序, 和execlpe相同, 可是提供了環境變量字典env

10.10 execvpe(cmd, arglist, env) 執行外部程序, 和execvpe相同, 可是提供了環境變量env

10.11 spawn*(mode, file, args[, env]) 在一個新的進程中執行路徑, args做爲參數, 環境變量env無關緊要, 模式用於顯示不一樣的操做模式.  這個系列的函數和fork結合exec系列函數功能類似, 由於spawn系列的函數在新的進程中執行命令.  可是不須要調用兩個函數來建立進程, 並讓這個進程執行命令;  另外有一點不一樣的是, 使用spawn系列的函數, 必須傳入spawn的魔法模式參數mode……在一些操做系統(好比嵌入式實時操做系統RTOS), spawn比fork要快不少…..其餘狀況的操做系統一般使用寫實拷貝.

10.12 wait()  等待進程完成(一般和fork和exec*()聯合使用)   子進程中的exit()被調用意味着子進程的完成

10.13 waitpid(pid, options)  等待指定的子進程完成

10.14 popen(cmd, mode = ’r’, buffering = -1)  執行字符串cmd, 返回一個類文件對象做爲運行程序通訊句柄, 默認爲讀取模式和默認系統緩衝.  實際上就是文件對象和system()函數的結合.

10.15 startfile(path)   用關聯的程序執行路徑.

11 subprocess模塊: python2.3開始, popen5模塊開始開發, 開始命名使用了popen*()系列函數的傳統, 最終被命名爲subprocess, 其中一個類叫Popen, 在該類中實現了大部分的面向進程的函數. 

11.1 call()函數能夠取代os.system():

import subprocess

res = subprocess.call((‘ls’, ‘/’))  #調用call執行ls命令查看/目錄下文件

res  //res是調用call的返回值.

11.2 Popen實例取代os.popen():

import subprocess

f = subprocess.Popen((‘ls’, ‘/’), stdout = subprocess.PIPE).stdout

data = f.readline()

f.close()

print data

12 相關函數:

12.1 os/popen2.popen2()  執行文件, 打開文件, 重新建立的運行程序讀取stdout, 或者向該程序寫(stdin)

12.2 os/popen2.popen3()  和popen2功能相同, 可是能夠從運行程序的stder中讀取數據了

12.3 os/popen2.popen4()  和popen3功能相同, 這個版本中stdout和stderr能夠結合起來工做

12.4 commands.getoutput()   在子進程中執行文件, 以字符串返回全部的輸出.

12.5 subprocess.call()   建立subprocess的便捷函數.   Popen等待命令完成, 而後返回狀態代碼;   與os.system類型, 但更靈活.

13 結束執行:  結束執行一般是程序執行完畢, 另一種狀況是使用異常處理來結束程序的運行.  還有一種方法就是建造一個清掃器, 將主要代碼放在if語句中, 在沒有錯誤的狀況下執行, 於是可讓錯誤的狀況正常的終結…  在有些時候, 也須要在退出調用程序的時候, 返回錯誤代碼. 用來代表發生了什麼事.

13.1 sys.exit()和SystemExit

13.1.1 sys.exit([status]): 接受一個無關緊要的參數status, status用來描述退出狀態, 也就是退出以後的返回消息.  status默認爲’0’

13.1.2 當調用sys.exit()時, 就會引起SystemExit()異常, 除非對異常進行監控(只有專門捕獲該異常纔會生效), 不然異常不會被捕捉或處理, 解釋器會用給定的狀態參數退出.  若是沒有給出狀態參數, 默認爲0…

13.1.3 退出以後, 狀態碼是返回給該程序的調用者的.

13.2 sys.exitfunc(): 該函數默認是不可用的.  能夠經過改寫提供額外的功能.

13.2.1 當調用了sys.exit()並在解釋器退出以前, 就會調用這個函數.  該函數不帶任何參數, 因此, 建立的函數也要是無參的.

13.2.2 若是sys.exitfunc已經被先前定義的exit函數覆蓋了, 最好的方法是把這段代碼做爲本身的exit()函數的一部分來執行.  通常而言, exit函數用於執行某些類型的關閉活動, 好比關閉文件和網絡鏈接, 最好用於完成維護任務, 好比釋放先前保留的系統資源.

13.2.3 設置一個exit()函數:

import sys

prev_exit_func = getattr(sys, ‘exitfunc’, None)  #獲取原來的exitfunc, 若是沒有獲得None

 

def my_exit_func(old_exit = prev_exit_func):

         ###########

         # execute clean work  執行清理工做

         ###########

         if old_exit is not None and callable(old_exit):

                   old_exit()  # 若是存在原來的exitfunc , 就調用它.

 

sys.exitfunc = my_exit_func  把新的exit函數註冊到sys.exitfunc

13.3 os._exit(): 以前的sys.exit()和sys.exitfunc()都會執行一些清理工做, 而os._exit()不會執行任何清理工做就直接退出.  而且, 該函數是和平臺相關的, 適用於Unix類系統和Win32平臺.   語法是os._exit(status)

13.4 os.kill(pid, sign)  接受進程id, 模擬傳統的unix函數來發送信號給進程, 發送的典型的信號是: SIGINT, SIGQUIT, SIGKILL, 使程序結束.

14 各類操做系統的接口見書618頁列表.

14.1 用#!/usr/bin/env python 表示用系統默認的python運行

14.2 只有在修改文件的權限爲可執行的時候纔有區別

14.3 若是用 python file.py 系統就會忽略這一句

15 支持管道操做的shell:

'''

Created on 2009-10-21

 

@author : selfimpr

@blog : http://blog.csdn.net/lgg201

@E-mail : lgg860911@yahoo.com.cn

'''

 

from sys import stdout

from subprocess import Popen, PIPE

 

def pipecmd(cmdstr):

    if isinstance(cmdstr, str): # estimate if the argument is string

        cmds = cmdstr.split('|') # split intact cmdstr to sigle command

        cmds = [cmd.strip() for cmd in cmds] # strip space character

        length = len(cmds)

        popens = []

        for index, cmd in enumerate(cmds): # each all the commands

            cmd_args = cmd.split(' ')

            cmd_args = [arg.strip() for arg in cmd_args]

            try:

                #################

                # get all the instance of Popen

                #################

                popens.append(eval('Popen(cmd_args%(stdin)s%(stdout)s)' % \

                               {'stdin': '' if index == 0 else ', stdin=PIPE', \

                                'stdout': ', stdout=stdout' if index == length - 1 else ', stdout=PIPE'}))

            except OSError, e:

                print 'arises os error'

        #################

        # process pipe

        #################

        prev = None

        for index, popenobj in enumerate(popens):

            if not prev:

                prev = popenobj

                continue

            popenobj.stdin.write(prev.stdout.read())

            prev = popenobj

正則表達式(chapter15)

1 查找和匹配:

1.1 搜索是在字符串任意部分中查找匹配的模式.

1.2 匹配是判斷一個字符串是否能從開始處所有或部分的匹配某個模式.

1.3 查找和匹配經過search, match方法實現.

2 重要的概念:

2.1 字符集合: 能夠匹配的字符

2.2 子組匹配: 提供用一個正則表達式提取多組值

2.3 模式匹配重複次數: 一個字符或子組的重複出現次數

3 \A匹配開始, \Z匹配結束, 是由於有些鍵盤不支持^和$符號.

4 中括號中只有或的關係

5 中括號第一個字符指定爲^表示不匹配中括號內任何字符.

6 問號跟在表示次數的符號後面表示使用非貪婪模式匹配.

7 ?:代表一組是非捕獲組

8 核心函數和方法:

8.1 compile(pattern, flags=0): 對正則表達式模式進行編譯.  其中flags是一個標記, 對於同一個pattern, flags用來指示是否區分大小寫, 是否多行匹配等問題.

8.2 match(pattern, string, flags = 0)  嘗試用正則表達式pattern匹配字符串string…若是匹配成功, 返回一個匹配對象, 不然返回None

8.3 search(pattern, string, flags = 0)  在字符串string中查找正則表達式模式pattern的第一次出現, 匹配成功返回匹配對象, 不然返回None

8.4 findall(pattern, string[, flags]) 在字符串string中查找正則表達式模式pattern的全部非重複出現, 返回一個匹配對象的列表.  若是正則表達式沒有分組, 直接返回查找獲得的列表, 若是正則表達式有分組, 則返回全部的子組的匹配結果.  若是正則表達式有子組, 而且獲得了屢次匹配, 那麼返回的結果是一個元組的列表, 每一個元組分別表示一次匹配成功後獲得的全部子組的匹配結果.

8.5 finditer(pattern, string[, flags])  和findall相同, 可是返回的是一個迭代器.

8.6 split(pattern, string, max = 0)  根據正則表達式pattern中的分隔符把字符串string分隔成爲一個列表. 返回成功匹配的列表, 最多分隔max次(默認分隔全部匹配的地方)

8.7 sub(pattern, repl, string, max = 0)  把字符串string中的全部匹配正則表達式pattern的地方替換成字符串repl, 若是max值沒有給出, 則對全部匹配地方進行替換.

8.8 subn, 和sub相同, 可是會返回替換次數.  subn返回一個元組, 元組第一個元素是替換後的字符串, 元組第二個元素是替換的次數.

8.9 group(num = 0)  返回所有匹配對象, 或指定子組編號

8.10 groups()   返回一個包含所有匹配的子組的元組.  若是沒有成功匹配, 返回一個空的元組.

9 模塊函數在對正則表達式進行預編譯以後會進行緩存, 可是仍是建議使用本身的預編譯正則表達式, 由於即使解釋器緩存了正則表達式, 那也須要查找.  python1.5.2中, 緩存區能夠容納20個已編譯的正則表達式對象, 在1.6版本中, 因爲添加了對Unicode的支持, 編譯引擎速度變慢, 因此, 緩存區被擴展到能夠容納100個已編譯的regex對象.

10 (?...)  子組內使用?開始表示該組有特殊含義

11 (?:…)非捕獲組

12 (?P<name>…)有名稱組

13 (?P=name)  匹配以前使用(?P<name>…)指定了名稱的一個組相同的內容

14 (?#...)  正則表達式的註釋文本

15 (?iLmsux): i  忽略大小寫, L  依賴本地字符, m  多行匹配,   s  點號匹配全部, u Unicode字符串,   x  貪婪匹配

16 (?=…)  向前斷言是…    表示匹配該元組內的元素, 可是, 不消耗字符串.  例如re.match(‘abc(?=e).*’, ‘abcdef’) 是匹配不成功的, 由於匹配到c結束以後, 使用子組匹配e匹配不到, 因此匹配失敗, 修改成re.match(‘abc(?=d).*’, ‘abcdef’)匹配獲得的結果則是abcdef, 由於匹配到c結束以後, 用子組匹配d, 匹配成功, 可是, 字符串沒有被消耗, 因此, 後面的.*繼續從字符串的d開始匹配.

17 (?!...)   向前斷言非…    和(?=…)相反, 不消耗字符串的前提下, 匹配字符串要和子組內指定的模式不匹配纔可以匹配成功.  例如re.match(‘abc(?!e).*’, ‘abcdef’)就可以匹配成功, 由於c匹配結束以後, 使用子組匹配e, 匹配失敗了, 因此能夠繼續向下.

18 (?<=…)  向後斷言是… 和向前斷言是相同

19 (?<!...)  向後斷言非… 和向前斷言非相同

20 (?(id/name)yes-pattern | no-pattern)  若是指定id或name的組匹配成功(存在匹配獲得的字符串, 而不能是?, + {0, n}等次數匹配獲得的0次), 那麼使用yes-pattern指定的規則匹配, 若是指定的組匹配獲得的是0次, 那麼使用no-pattern指定的規則匹配.  例如: (?<starttag><)?html(?(starttag)>), 若是starttag組匹配<獲得了1次(或以上), 那麼(?(starttag)>)這個組使用>進行匹配, 不然, 使用|後的no-pattern匹配, 因爲這裏沒有指定管道|, 因此, 這一組就不匹配.  所以, 上面的這個正則表達式能夠匹配<html>也能夠匹配html

21 regular1|regular2  使用regular1匹配或使用regular2匹配

22 正則表達式選項: 使用(?iLmsux)指定, 而且, 這個開關的開啓能夠在正則表達式的任意位置, 但在正則表達式全局有效.  i L m s u x是區分大小寫的

22.1 i  忽略大小寫(不傾向於當前的本地環境)

22.2 L  使\w, \W, \b, \B, \s, \S等特殊字符依賴本地環境表意

22.3 m  多行匹配, 若是指定了^或$, 則表示每一行的開始或結尾都要符合規則, 而且, 指定以後獲取match對象, 使用group()接口只能獲取到第一行的匹配結果, 要想得到全部行的匹配結果須要使用re.findall接口, 返回的列表中, 每一行的匹配結果做爲列表的一個元素, 若是每一行有多個子組匹配, 那麼每一行的匹配返回的是一個元組, 該行內每一個子組的匹配結果是對應元組中的元素.

22.4 s  使.匹配包含換行符在內的全部字符.  不打開s開關的時候, .不能匹配換行符

22.5 u  使\w, \W, \b, \B, \d, \D, \s, \S依賴於unicode字符串進行匹配

22.6 x   使用冗長的方式描述正則表達式. 這個狀態下, 普通的空格會被忽略, 能夠直接用#給正則表達式加註釋, 這樣使用, 能夠使正則表達式更加易讀.  若是要在這樣的正則中匹配空格, 就使用\轉義的空格.

23 python正則表達式在使用flags指定選項開關時, 也使用了位操做進行受權

24 在正則表達式中使用原始字符串r’’, 之因此使用原始字符串, 是由於正則表達式的一些特殊字符好比\b和ASCII字符衝突, \b在正則表達式中表示單詞邊界, 可是ASCII字符中表示退格鍵.  使用\\b能夠解決這種衝突, 讓\\b表明單詞邊界, 可是, 更好的方法是在建立正則表達式的時候使用原始字符串r’’, 這樣就不會存在這個問題了, 並且不用爲了一些衝突的字符用多一個\的方式搞亂正則表達式.

25 使用斷言的時候, 用match接口不能返回匹配結果…

網絡編程(chapter16)

1 什麼是客戶/服務器架構:

1.1 服務器是一個軟件或硬件, 用於提供客戶須要的’服務’,  服務器存在的惟一目的就是等待客戶的請求, 給這些客戶服務, 而後等待其餘請求.

1.2 客戶連上一個服務器, 提出本身的請求, 發送必要的數據, 而後就等待服務器的完成請求或說明失敗緣由的反饋.  服務器不停的處理外來的請求, 而客戶一次只能提出一個服務的請求, 等待結果.  而後結束這個事務.  一個事務結束後, 客戶再提出其餘的請求會被看做是另外一個事務.

2 NFS: Network File System, 是Sun公司的網絡文件系統.

3 軟件的C/S結構主要是程序的運行, 數據的發送與接收, 合併, 升級或其餘的程序或數據的操做.

4 遠程桌面鏈接其實是GUI的遠程數據發送.

5 架構:  服務端創建一個通信端點, 監聽服務端口(服務啓動時能夠向潛在客戶端發送廣播), 客戶端建立一個通信端點, 有目的的鏈接到服務器.  這樣, 客戶端就可以提出請求, 請求中, 能夠包含必要的數據交互, 一旦請求處理完成, 客戶受到了數據, 通信就結束了.

6 套接字: 具備’通信端點’概念的計算機網絡數據結構.  網絡化的應用程序在開始任何通信以前都必需要建立套接字. 

6.1 起源於20世紀70年代加利福尼亞大學伯克利分銷版本的Unix, 也就是BSDUnix. 因此, 套接字也被稱爲伯克利套接字或BSD套接字.

6.2 最先套接字用於同一臺pc上的多個應用程序之間的通信, 也就是進程間通信, 或IPC.

6.3 套接字家族:

6.3.1 AF_UNIX: POSIX1.g標準中也叫AF_LOCAL, 表示’地址家族: UNIX’.  老一點的系統中, 地址家族被稱爲’域’或’協議家族’, 使用縮寫’PF’.  爲了向後兼容, 不少系統中AF_LOCAL_和AF_UNIX是等價的.  AF_LOCAL在2000-2001年被列爲標準, 將會替代AF_UNIX.  這個家族的套接字數基於文件系統的, 用於同一臺pc上的不一樣進程進行通信

6.3.2 AF_INET: 地址家族: Internet, 另外還有一種地址家族AF_INET6用於IPv6尋址上.

6.3.3 python2.5中加入了一種Linux套接字的支持: AF_NETLINK(無鏈接)讓用戶代碼與內核代碼之間的IPC能夠使用標準BSD套接字接口.

6.4 套接字有兩種: 文件型和網絡型.

6.5 套接字地址: 主機和端口就至關於電話的區號和電話號碼.

6.6 合法的端口號是0-65535, windows中小於1024的端口號系統保留, Unix操做系統, 經過/etc/services文件得到系統保留端口號.

6.7 面向鏈接的套接字:

6.7.1 通信以前, 必定要創建一套鏈接. 也被稱爲’虛電路’或’流套接字’

6.7.2 提供了順序的, 可靠的, 不會重複的數據傳輸, 並且也不會被加上數據邊界.  也就是說每個要發送的信息, 可能會被拆分紅多份. 每一份都會很少很多的正確的到達目的地, 而後被從新按順序拼裝起來, 傳遞給正在等待的應用程序.

6.7.3 TCP: 傳輸控制協議(Transfer Controll Protocol), 建立TCP套接字就得在建立的時候, 指定套接字類型爲SOCK_STREAM

6.7.4 TCP套接字採用SOCK_STREAM做爲名字, 表達了它做爲流套接字的特色, 因爲這些套接字使用Internet協議來查找網絡中的主機, 這樣造成了整個系統, 通常會由這連個協議說起, 即TCP/IP

6.8 面向無鏈接的套接字:

6.8.1 數據報型的無鏈接套接字.

6.8.2 無需創建鏈接就能通信, 數據到達的順序, 可靠性和數據不重複性沒法保證, 數據報會保留數據邊界, 也就是說數據不會像面向鏈接的協議那樣被拆分紅小塊.

6.8.3 UDP: 用戶數據報協議(User Datagram Protocol). 建立UDP套接字須要在建立的時候指定套接字類型爲SOCK_DGRAM.

6.8.4 UDP也使用Internet協議查找網絡中的主機, 造成整個系統, 所以, 稱爲UDP/IP.

7 Python中的網絡編程: socket模塊. 其中的socket()函數用來建立套接字.

7.1 socket()函數: socket(socket_family, socket_type, protocol=0): socket_family是套接字家族(AF_UNIX或AF_INET), socket_type能夠是SOCK_STREAM或SOCKET_DGRAM, protocol通常不填, 默認是0.

7.2 建立TCP/IP套接字: tcpsocket = socket.socket(socket.AF_INET, socket.SOCKET_STREAM)

7.3 建立UDP/IP套接字: udpsocket = socket.socket(socket.AF_INET, socket.SOCKET_DGRAM)

8 套接字對象的內建方法:

8.1 服務端套接字函數:

8.1.1 s.bind(address)綁定地址(主機, 端口號等)到套接字. address的格式依賴於當前的socket的家族, python-library  page600給出了家族address的相關信息, 其中, 使用INET就愛組的套接字時, 對於HOST設置爲’’時, 表示能夠將套接字綁定到任何有效的地址上.

8.1.2 s.listen(backlog)  開始TCP監聽. backlog指定鏈接隊列的最大數量, 最小是1, 最大依賴於系統(通常是5)

8.1.3 s.accept()  被動接受TCP客戶的鏈接, 阻塞式的等待鏈接的到來.

8.2 客戶端套接字函數

8.2.1 s.connect()  主動初始化TCP服務鏈接

8.2.2 s.connect_ex()  connect()函數的擴展版本, 出錯是返回出錯碼, 而不是拋出異常.

8.3 公共用途的套接字函數

8.3.1 s.recv(buffersize[, flag])  接受TCP數據, buffersize指定緩衝區大小, flag不知道意思, 返回接受到的數據

8.3.2 s.send(data[, flag])   發送TCP數據, data爲string類型的數據, flag不知道意思, 返回發送數據的字節數

8.3.3 s.sendall()  完整發送TCP數據

8.3.4 s.recvfrom(buffersize[, flags])   接受UDP數據, buffersize指定緩衝區大小, 可是, 接受到超過buffersize的數據的時候, 會發生異常.

8.3.5 s.sendto(string[, flags], address)  發送UDP數據, string是要發送的數據, flags默認是0, address是要發送的地址, 依賴於套接字的家族.

8.3.6 s.getpeername()  鏈接到當前套接字的遠端的地址

8.3.7 s.getsocketname()  當前套接字的地址

8.3.8 s.getsocketopt()  返回當前套接字的參數

8.3.9 s.setsocketopt()  設置當前套接字的參數

8.3.10 s.close()  關閉套接字.

8.4 面向塊的套接字方法:

8.4.1 s.setblocking()  設置套接字的阻塞與非阻塞模式

8.4.2 s.settimeout()  設置阻塞套接字操做的超時時間

8.4.3 s.gettimeout()  獲取阻塞套接字操做的超時時間

8.5 面向文件的套接字函數

8.5.1 s.fileno()  套接字的文件描述符

8.5.2 s.makefile()  建立一個與套接字關聯的文件.

9 建立TCP服務器:

9.1 建立服務器套接字socket()

9.2 把地址綁定到套接字上bind()

9.3 監聽鏈接listen()

9.4 無限循環開啓接受請求

9.5 接受客戶的鏈接accpet()

9.6 開啓通信循環

9.7 處理客戶的請求recv()/send()

9.8 客戶關閉close()

9.9 服務器關閉

10 建立TCP客戶端:

10.1 建立客戶端套接字socket()

10.2 嘗試鏈接服務器connect()

10.3 通信循環

10.4 對話send()/recv()

10.5 關閉套接字close()

11 建立UDP服務器: UDP是面向無鏈接的, 因此只要等待鏈接就能夠了

11.1 建立一個服務器套接字socket()

11.2 綁定服務器套接字bind()

11.3 服務端循環

11.4 對話recvfrom()/sendto()

11.5 關閉服務器套接字close()

12 建立UDP客戶端

12.1 建立客戶端套接字socket()

12.2 通信循環

12.3 對話sendto()/recvfrom()

12.4 關閉客戶端套接字close()

13 套接字模塊的屬性

13.1 數據屬性

13.1.1 AF_UNIX, AF_INET, AF_INET6, Python支持的套接字家族

13.1.2 SOCK_STREAM, SOCK_DGRAM  套接字類型

13.1.3 has_ipv6  是否支持IPV6

13.2 異常

13.2.1 error  套接字相關錯誤

13.2.2 herror  主機和地址相關錯誤

13.2.3 gai  地址相關錯誤

13.2.4 timeout  超時

13.3 函數

13.3.1 socket()  建立套接字對象

13.3.2 socketpair()   建立套接字對象

13.3.3 fromfd()  用一個已經打開的文件描述符建立一個套接字對象

13.4 數據屬性

13.4.1 ssl()  在套接字初始化一個安全套接字層, 不作證書驗證

13.4.2 getaddrinfo()  獲得地址信息

13.4.3 getfqdn()  返回完整的域的名字

13.4.4 gethostname()  獲得當前主機名

13.4.5 gethostbyname()  由主機名獲得對應的ip地址

13.4.6 gethostbyname_ex()   gethostbyname()的擴展版本, 返回主機名, 主機全部別名和IP地址列表.

13.4.7 gethostbyaddr()  由IP地址獲得DNS信息, 返回一個相似gethostbyname_ex()的3元組

13.4.8 getprotobyname()  由協議名獲得對應的號碼

13.4.9 getservbyname()  由服務名獲得對應的端口號或相反

13.4.10 getservbyport   兩個函數中, 協議名都是可選的.

13.4.11 ntohl()/ntohs()   把一個整數由網絡字節序轉爲主機字節序

13.4.12 htonl()/htons()  把一個整數由主機字節序轉爲網絡字節序

13.4.13 inet_aton()/inet_ntoa()  把IP地址轉爲32位整型, 以及反向函數(僅對IPV4有效)

13.4.14 inet_pton()/inet_pton()  把IP地址轉爲二進制格式以及反向函數(僅對IPV4有效)

13.4.15 getdefaulttimeout()/setdefaulttimeout()   獲取/設置默認的套接字超時時間.(浮點數)

14 SocketServer模塊: 用於簡化網絡客戶與服務器的實現.

14.1 BaseServer  包含服務器的核心功能與混合(mix-in)類的鉤子功能, 該類用於派生, 不要直接生成

14.2 TCPServer/UDPServer  基本的網絡同步TCP/UDP服務器

14.3 UnixStreamServer/UnixDatagramServer  基本的基於文件同步的TCP/UDP服務器

14.4 ForkingMixIn  實現了核心的進程化或線程化的功能, 用於和服務器類進行混合, 提供一些異步特性.

14.5 ThreadingMixIn   和ForkingMixIn相同, 提供線程服務, 不要直接生成這個類的實例

14.6 ForkingTCPServer/ForkingUDPServer   ForkingMixIn和TCPServer/UDPServer的組合

14.7 ThreadingTCPServer/ThreadingUDPServer   ThreadingMixIn和TCPServer/UDPServer的組合

14.8 BaseRequestHandler  包含處理服務請求的核心功能.  只用於派生新的類, 不要直接生成該類對象,    能夠考慮使用StreamRequestHandler或DataRequestHandler

14.9 StreamRequestHandler/DatagramRequestHandler   TCP/UDP服務器的請求處理類的一個實現.

15 使用SocketServer模塊建立一個TCP服務器, SocketServer的請求處理器的默認行爲是接受鏈接, 獲得請求, 而後就關閉鏈接, 跟UDP的服務方式相似, 爲了保持鏈接, 須要重寫請求處理器中的其餘方法.

15.1 實現一個繼承請求處理器(StreamRequestHandler)的類, 重寫handle方法

15.2 實例化一個TCPServer的實例, 傳入本身的請求處理器類.

15.3 開啓服務: tcpserver.serve_forever()

16 Twisted框架(http://twistedmatrix.com)

16.1 Twiste是一個徹底事件驅動的網絡框架.  容許使用和開發徹底異步的網絡應用程序和協議

16.2 包含: 網絡協議, 線程, 安全和認證, 聊天/即便通信, 數據庫管理, gaunxi 數據庫集成, 網頁/互聯網, 電力郵件, 命令行參數, 圖形界面集成.

16.3 使用Twisted Reactor TCP服務器

16.3.1 服務端:

16.3.1.1 繼承twisted.internet.protocol.Protocol實現一個服務協議

16.3.1.2 服務協議類中重寫connectionMake(self)方法: 使用self.transport.getPeer().host能夠獲取客戶端信息

16.3.1.3 服務協議類中重寫dataReceived(self, data)方法, data就是接收到的數據, 在這裏能夠使用self.transport.write()向客戶端發送數據

16.3.1.4 主程序中, 建立一個twisted.internet.protocol.Factory()實例, 並設置factory.protocol = 上面實現的服務協議類

16.3.1.5 調用twisted.internet.reactor.listenTCP(PORT, factory)開始監聽

16.3.1.6 調用twisted.internet.reactor.run()開啓服務

16.3.2 客戶端

16.3.2.1 繼承twisted.internet.protocol.Protocol實現一個客戶端的協議類

16.3.2.2 協議類中重寫sendData(self)方法, 用於發送數據的控制

16.3.2.3 協議類中重寫connectionMade(self)方法, 用於建立鏈接, 因爲是客戶端, 這裏只要調用sendData就能夠了(也就是鏈接併發送數據)

16.3.2.4 協議類中重寫dataReceived(self, data)接收並處理數據, 並進行響應

16.3.2.5 繼承twisted.internet.protocol.ClientFactory實現一個客戶端的工廠類

16.3.2.6 客戶端工廠類中定義protocol屬性爲上面實現的協議類

16.3.2.7 客戶端工廠類中定義clientConnectionLost = clientConnectionFailed = lambda self, connector, reason: reactor.stop() 指示鏈接失敗處理方式

16.3.2.8 主程序中調用twisted.internet.reactor.connectTCP(HOST, PORT, factory)鏈接服務器

16.3.2.9 reactor.run()開啓客戶端服務

17 相關模塊:

17.1 select: 一般在底層套接字程序中與socket模塊聯合使用, 提供的select()函數能夠同時管理套接字對象, select()函數會阻塞, 直到至少有一個套接字準備好要進行通信的時候才退出.

17.2 asyncore/asynchat和SocketServer模塊在建立服務器方面都提供了高層次的功能, 因爲是基於socket和select模塊, 封裝了全部的底層代碼, 因此開發簡單.  async*模塊是惟一的異步開發支持庫.

網絡客戶端編程(chapter17)

1 常見的文件傳輸協議:

1.1 FTP

1.2 UUCP: Unix-to-Unix複製協議

1.3 HTTP

1.4 rcp: Unix下的遠程文件複製指令

1.5 較rcp更靈活的scp和rsync

2 FTP是C/S中的一個特例, 客戶端和服務器都使用兩個套接字來通信, 一個是控制和命令端口(21), 另外一個是數據端口(20)

 

3 FTP的客戶端和服務器使用指令和控制端口發送FTP協議, 數據經過數據端口傳輸.

4 FTP有主動和被動兩種模式

4.1 只有主動模式服務器才使用數據端口.  服務器將20端口設置爲數據端口後, 它」主動」鏈接客戶端的數據端口.

4.2 被動模式中, 服務器只是告訴客戶端它的隨機端口的號碼, 客戶端必須主動創建數據鏈接, 在這種模式下, FTP服務器在創建數據鏈接時是被動的.

5 python構建FTP客戶端

5.1 使用ftplib模塊

5.2 程序流程

5.2.1 鏈接到服務器, 建立一個ftplib.FTP(HOST)實例

5.2.2 登陸ftp.login(‘anonymous’,  ‘guess@who.org’), 調用ftp的登陸接口

5.2.3 發出服務請求(有可能有返回信息)

5.2.4 退出  ftp.quit()

5.3 ftplib.FTP類方法

5.3.1 login(user = ‘anonymous’, passwd = ‘anonymous@’, acct = ‘’)登陸到FTP服務器, acct參數的意義是賬號的更詳細的描述信息.

5.3.2 pwd()  獲得當前工做目錄

5.3.3 cwd(path)  改變當前工做目錄

5.3.4 dir([path[, …[, cb]]])  顯示path目錄中的內容, 可選參數cb是一個回調函數, 會被傳給retrlines()方法.  回調函數能夠接受一個參數, 每次讀取的一行會被傳入回調函數進行處理.

5.3.5 nlst([path[, …]])與dir()相似, 但返回一個文件名的列表, 而不是顯示這些文件名

5.3.6 retrlines(cmd [, cb])  個頂FTP命令(如RETR filename), 用於下載文本文件. 可選的回調函數cb用於處理文件的每一行

5.3.7 retrbinary(cmd, cb[, buffersize = 8192[, ra]])  與retrlines()相似, 只是這個指令處理二進制文件.   回調函數cb用於處理每一塊(塊大小默認爲8k)下載的數據

5.3.8 storlines(cmd, f)  給定FTP命令(如」STOR filename」), 以上傳文本文件.  要給定一個文件對象f

5.3.9 storbinary(cmd, f[, bs=8192])  與storlines()類型, 可是這個指令用來處理二進制而年間. 要給定一個文件對象f和一個上傳塊大小bs, 默認8kb

5.3.10 rename(old, new)  對遠程文件進行更名

5.3.11 delete(path)  刪除位於path的遠程文件

5.3.12 mkd(directory)  建立遠程目錄

5.3.13 rmd(directory)  刪除遠程目錄

5.3.14 quit()   關閉鏈接並退出

6 FTP的處理細節及其餘:

def storbinary(self, cmd, fp, blocksize=8192):

    '''Store a file in binary mode.'''

    self.voidcmd('TYPE I')

    conn = self.transfercmd(cmd)

    while 1:

        buf = fp.read(blocksize)

        if not buf: break

        conn.sendall(buf)

    conn.close()

    return self.voidresp()

 

def storlines(self, cmd, fp):

    '''Store a file in line mode.'''

    self.voidcmd('TYPE A')

    conn = self.transfercmd(cmd)

    while 1:

        buf = fp.readline()

        if not buf: break

        if buf[-2:] != CRLF:

            if buf[-1] in CRLF: buf = buf[:-1]

            buf = buf + CRLF

        conn.sendall(buf)

    conn.close()

    return self.voidresp()

6.1 上面是ftplib.py中的storbinary和storlines兩個函數的源碼, 經過分析源碼, 能夠看出, python支持的ftp客戶端程序編寫, 主要是基於FTP服務端提供的FTP命令, 不管何種方式, 最基礎的接口是仍然是命令的發送, FTP經過首先發送一個命令, 獲取到服務端的響應, 響應正常, 則返回一個socket鏈接, 對方等待文件傳輸, 若是響應失敗, 則返回相應的異常消息便可.

6.2 四種常見FTP客戶端

6.2.1 命令行客戶端, 提供本身的命令接口供用戶和服務端交互

6.2.2 GUI客戶端: 圖形用戶界面

6.2.3 網頁瀏覽器: 瀏覽器通常都容許直接的FTP交互

6.2.4 定製程序: 用於特殊目的的FTP文件傳輸程序, 通常不容許用戶與服務器接觸.

7 Usenet和網絡新聞組:

7.1 Usenet新聞系統是一個全球存檔的’電子公告板’.

7.2 Usenet整個系統由大量計算機組成, 計算機之間共享Usenet上的帖子.  用戶發佈的帖子會經過Usenet傳播到其餘相連的計算機上上.

7.3 每一個系統都有一個它已經’訂閱’的新聞組的列表, 只接收它感興趣的新聞組裏的帖子.

7.4 系統能夠設置權限控制(身份驗證, 操做權限控制等.)

8 網絡新聞傳輸協議(NNTP): 供用戶在新聞組中下載或發表帖子的協議.

 

8.1 加利福尼亞大學聖地亞哥分校和伯克利分銷建立, 記錄在RFC977. 1986年2月公佈, 其後的更新記錄在RFC2980(2000年10月公佈)

8.2 NNTP只使用119端口作通信.

9 python中的NNTP(nntplib.NNTP)

9.1 流程

9.1.1 鏈接服務器  n = nntplib.NNTP(‘nntp_server’)

9.1.2 登陸(若是須要)  nntplib.NNTP(host[, port[, username[, password[, readermode][, usenetrc]]]])

9.1.3 發送請求: resp, count, first, last, name = n.group(‘comp.lang.python’)

9.1.4 退出: n.quit()

9.2 nntplib.NNTP類的方法

9.2.1 group(name)  選擇一個組的名字.  返回一個元組(resp, count, first, last, name), 分別是: 服務器返回信息, 文章數量, 第一個和最後一個文章的號碼, 組名.  返回的全部數據都是字符串, 返回的組名和傳入的name應該相同

9.2.2 xhdr(header, string[, file])  發送一個XHDR命令, XHDR命令沒有在RFC中定義, 可是是一個公共的擴展.header是消息頭的關鍵字(好比subject), string參數能夠有一個表單’first-last’意思是第一個和最後一個文章號碼去搜索, 返回一個元組(response, list) 其中list是一個元組的列表(id, text), 其中, id是文章的號碼(string類型), text是文章內容..    若是指定file參數, XHDR命令的輸出會存儲到指定的文件中, 若是file是一個string, 該方法會按照file指定的名稱打開一個文件, 寫入並關閉.  若是file是一個文件對象, 就直接調用write方法將XHDR的輸出寫入到文件.

9.2.3 body(id[, ofile])  給定文章的id, id能夠是消息的id(放到尖括號中), 或一個文章號(字符串), 返回一個元組(resp, anum, mid, data): 服務器返回消息, 文章號, 消息id(放到尖括號中), 和文章全部行的列表或把數據輸出到ofile指定的文件中

9.2.4 head(id)  和body相似, 可是, 返回的元組中那個行的列表中只包含了文章的標題

9.2.5 article(id)   和body相似, 只是返回的元組中的那個行的列表中只包含了文章的標題和內容

9.2.6 stat(id)  讓文章的指針指向id, 返回的仍是和body返回同樣的一個元組, 可是不包含文章的數據.

9.2.7 next()   用法和stat()相似, 只是將文章的指針移到下一篇文章.

9.2.8 last()  和next()同樣, 只不過是移到了最後一篇文章.

9.2.9 post(ufile)  上傳ufile文件對象中的內容(使用ufile.readline())  並在當前新聞組發表

9.2.10 quit()  關閉鏈接, 而後退出

10 交互式NNTP的簡單實現(無網絡條件暫時未實現.)

11 電子郵件: RFC2822中定義: 消息由頭域(消息頭)以及後面可選的消息體組成.  郵件頭是必要的

11.1 消息傳輸代理(MTA, Message Transfer Agency): 郵件交換主機上運行的一個服務器程序, 負責郵件的路由, 隊列和發送工做.  也就是郵件從源主機到目的主機所要通過的跳板.

11.2 MTA負責的事情:

11.2.1 如何找到消息應該去的下一臺MTA: 由DNS來查找目的域名的MX(Mail eXchange, 郵件交換)來完成, 對於最後的收件人來講是非必須的, 但對於其餘的跳板來講, 是必須的.

11.2.2 如何與另外一臺MTA通信: 依靠消息傳輸系統(MTS, MTA之間通信使用的協議, Message Transport System), 只有兩個MTA都使用這個協議時, 才能夠通信..  因爲互聯網絡的複雜性, 1982年提出了SMTP(簡單郵件傳輸協議, Simple Mail Transfer Protocol)

11.3 SMTP是因特網上MTA之間用於消息交換的最經常使用的MTS…被MTA用來把email從一臺主機傳送到另外一臺主機.  在發送email時, 必需要鏈接到一個外部的SMTP服務器.  此時, 郵件程序是一個SMTP客戶端, 對應的SMTP服務器就是消息的第一個跳板.

12 python中的SMTP: smtplib.SMTP

12.1 流程:

12.1.1 鏈接到服務器  n = smtplib.SMTP([host[, port[, local_hostname[, timeout]]]]):   若是給定了host和port參數, 初始化的時候就會自動調用connect接口去鏈接指定的SMTP服務器.  若是沒有正確的返回, 拋出一個SMTPConnectError, timeout參數用於指定超時的秒數

12.1.2 登陸(若是須要的話)  login(username, password)

12.1.3 發出服務請求  n.sendmail(from_addr, to_addr, msg[, mail_options, rcpt_options])

12.1.4 退出n.quit()

12.2 消息在傳輸過程當中, SMTP不能以任何理由修改郵件消息

12.3 smtplib.SMTP類方法: 多數e-mail發送程序中, sendmail和quit方法是必須的.

12.3.1 sendmail的全部參數都要遵循RFC2822, email地址要有正確的格式, 消息體要有正確的前導頭, 前導頭後面是兩個回車和換行(\r\n)對

12.3.2 RFC2822中要求的必須的頭信息只有發送日期和發送地址, 也就是Date:和From:

12.3.3 sendmail(from_addr, to_addr, msg[, mail_options, rcpt_options]): 將消息msg從from_addr發送到to_addr(列表或元組)…… ESMTP設置(mopts)和收件人設置(ropts)爲可選

12.3.4 quit()  關閉鏈接, 而後退出

12.3.5 login(username, password)  登陸到SMTP服務器

13 交互式SMTP:

smtp = smtplib.SMTP(‘smtp.qq.com’)   鏈接服務器

smtp.login(username, password)   登陸服務器

smtp.set_debuglevel(1)     //設置爲調試狀態

smtp.sendmail('285821471@qq.com ', 'lgg860911@yahoo.com.cn', '''From: 雷果國\r\nTo: 雷果國\r\nSubject: 你好.''')   發送郵件

smtp.quit()   退出…

14 郵件接收:

14.1 用於下載郵件的第一個協議叫作郵局協議, 目的是讓用戶的工做站能夠訪問郵箱服務器裏的郵件.

14.2 POP3是POP協議的最新版

14.3 IMAP: 交互式郵件訪問協議, 如今被使用的是IMAP4rev1

 

15 python中的pop3: poplib.POP3

15.1 流程

15.1.1 鏈接服務器: p  = POP3(‘pop.qq.com’)

15.1.2 登陸: p.user(), p.pass_()

15.1.3 處理

15.1.4 退出: p.quit()

15.2 示例:

import poplib

 

yahoo = poplib.POP3(‘pop.mail.yahoo.com.cn’)

yahoo.user(‘lgg860911’)

yahoo.pass_(‘2a0d1q22f9’)

yahoo.list()    //獲得郵件列表, 返回一個元組的列表, 元組中, 第一個元素是服務器返回消息, 第二個元素是消息的列表, 第三個元素是返回信息的大小.

yahoo.retr(192)   //根據郵件編號獲取郵件內容, 並將其設置爲’已讀’標誌.  返回一個和list同樣的元組

15.3 poplib中的方法

15.3.1 user(username)  發送用戶名登陸

15.3.2 pass_(password)   發送密碼

15.3.3 stat()   返回郵件的狀態, 長度爲2的元組(msg_ct, mbox_size)  是消息的數量和消息的總大小

15.3.4 list()

15.3.5 retr

15.3.6 dele(msgnum)根據郵件編號將其標記爲刪除.   大多數服務器在調用quit()後執行刪除操做

15.3.7 quit()  登出, 保存修改.  解鎖郵箱, 結束鏈接, 而後退出.

15.3.8 使用list()方法處理的時候, 參數msg_list的格式是: [‘msgnum msgsize’, …]其中, msgnum和msgsize分別是每一個消息的編號和消息的大小.

多線程編程(chapter18)

1 多線程編程的適合場景: 本質上就是異步的, 須要有多個併發事務, 各個事務的運行順序能夠是不肯定的, 隨機的, 不可預測的.  這種編程任務能夠被分紅多個執行流, 每一個流都有一個要完成的目標, 根據應用的不一樣, 這些子任務可能都要計算一箇中間結果, 用於合併獲得最後的結果.

1.1 運算密集型的任務通常都比較容易分隔出多個子任務, 順序或異步執行.

1.2 多個外部輸入源的任務使用單線程方式很難解決(可能得須要使用計時器方式實現.)

1.3 順序執行的程序必須使用非阻塞I/O或是帶有計時器的阻塞I/O, 由於用戶的如入到達是不肯定的.

2 使用多線程編程和一個共享的數據結構如Queue, 這種程序任務能夠用幾個功能單一的線程來組織:

2.1 UserRequestThread: 負責讀取客戶的輸入, 多是一個IO信道.  程序可能建立多個線程, 每一個客戶一個, 請求會被放入到隊列中

2.2 RequestProcessor: 一個負責從隊列中獲取並處理請求的線程, 會爲下面那種線程提供輸出

2.3 ReplyThread: 負責把給用戶的輸出取出來, 若是是網絡應用程序就把結果發送出去, 不然就保存到本地文件系統或數據庫中.

3 進程: 有時被稱爲重量級進程, 是程序的一次執行.  每一個進程都有本身的地址空間, 內存, 數據棧和其餘記錄其運行軌跡的輔助數據. 操做系統管理在其上運行的全部進程, 併爲這些進程公平的分配時間篇.  進程能夠經過fork和spawn操做來完成其餘任務.  進程之間的通信使用IPC.  而不能直接共享信息.

4 線程: 有時被成爲輕量級進程.  全部的線程都是運行在同一個進程中, 共享相同的運行環境.

4.1 三種狀態: 開始, 順序執行, 結束

4.2 線程擁有本身的指令指針, 記錄本身運行到什麼地方. 線程的運行可能被搶佔(中斷), 或暫時的被掛起(睡眠), 讓其餘的線程運行, 這也叫作讓步.

4.3 一個進程中的多個線程之間共享同一片數據空間, 因此, 線程之間的通信比進程之間的通信更加方便.

4.4 線程通常都是併發執行的, 並行和數據共享機制使得多任務合做成爲現實

4.5 危險性: 多線程同時訪問同一片數據的時候, 可能致使髒讀等狀況的發生.  這種狀況叫作競態條件, 這種危險的解決使用線程同步.

4.6 另外一個危險來源於阻塞: 有的函數會在完成以前阻塞住, 在沒有特別爲多線程作修改的狀況下, 這種」貪婪」的函數會讓CPU時間分配有所傾斜, 致使多線程分配到的運行時間不盡相同, 不公平.

5 線程或進程的並行, 實際上都是線性的, CPU分出時間片, 每一個進程, 線程會根據優先級等CPU時間片分配策略獲得相應的執行時間.

相關文章
相關標籤/搜索