第四章、Py之殼:程式結構
- 用"#"來註解
- 用"\"來延續多行
- 相等 "=="
- 不相等 "!="
- 小於 "<"
- 小於等於 "<="
- 大於 ">"
- 大於等於 ">="
- 成員資格 "in"
- 用if、elif、else來比較
※程式會依序檢查,不在 if 就會前往 elif 檢查,都不在 elif,則最後前往 else
※結尾需加上":",底下每一行 print 都要縮排
- 用while來重複執行
※ "+="為 加
- 用break來取消
※讓使用者輸入單字,會將單字的第一個字母改為大寫。若輸入"q"則印出'end'跳出迴圈
- 用continue來跳過
- 使用else來檢查中斷
※如果迴圈正常結束,沒有找到該物件,就可以執行else:把結果print出來
- 用for來迭代
※可以迭代的有字串、tuple、字典、集合...等
迭代字串會依次產生一個字元
迭代tuple或串列會一次產生一個項目
迭代字典則會產生鍵,要產生值用.value( )函式
可以用tuple來回傳鍵與值,用.items( )函式
- 用break來取消
- 用continue來跳過
- 使用else來中斷
- 用zip()來迭代多個序列
- 用zip配對tuple,再將它們傳入dict,變成字典
- 用range()來產生數字排列
※跟slice的用法很像(start, stop, step),最後一個值會是stop的前一個
- 生成式
- 串列生成式
[運算式 for 項目 in 可迭代項目]
※上面為串列生成式建構整數串列的方式
在第一行,你需要一個number變數來產生串列的值,將回結果放入number_list
第二個number是for迴圈的一部分
[運算式 for 項目 in 可迭代項目 if 條件式]
- 字典生成式
{ 鍵運算式 : 值運算式 for 項目 in 可迭代項目 }
※用set就不會重複計算同樣的字母
- 集合生成式
{運算式 for 項目 in 可迭代項目}
- 函式
- 使用"def 函式名稱():" 來定義
- 位置引數
※位置引數必須記得每個位置代表
- 關鍵字引數
※也可以將位置引數與關鍵字引數混合使用,但位置引數必須放在最前面的對應位
- 指定預設的參數值
※預設只能放在最後的選項(可以多個),如果提供引數話,函式就會使用它,而不是預設值
- 用" * "來收集引數
- 用" ** "來收集關鍵字引數
- 文件字串
- 函式是第一級公民
※對於Python,所有東西皆是物件。包括 數字、字串、tuple、串列、字典,函式也是第一級公民,可已將她們指派給便數、把他們當成引數給其他函式
- 內部函式
※你可以在函式的裡面定義函式
- Closure
※Closure對於沒接觸的人,理解起來較為複雜。
是一種由其他函式動態生成的函式, 用在巢狀宣告 function 或 lambda
在 closure object 被建立的同時,closure 所引用到的外層變數就已經確立了。因此, closure 所引用的變數,並不會因呼叫的位置改變而改變。永遠是引用 closure object 建立的那一瞬間,所看到的外層變數。
- 匿名函式: lamba( )函式
※因為enliven函式很簡短,所以可以將花換成lambda
這個lambda會取用一個引數叫做word,在冒號與結束括號之間的所有東西就是函式的定義
- 產生器
產生器式一種Python的序列建立物件,可已迭代很大的序列物件,但不需要在記憶體中建立或儲存整個序列
每當你迭代產生器時,他會記得上次被你呼叫時所在的位置,如不用每是從它的第一行,以相同的狀態開始
這或許很難理解。簡單來說range()這個函式就是一個產生器,裡面已經儲存了整個序列
以下為編寫一個新的產生器
※它是一種一般的函式,但他會用yield陳述式來回傳,而不是return
- 裝飾器
有時你會改變既有的函式,但不想更改原始碼,裝飾器(decorator)是一種函式,它會接收一個函式,並回傳另一個函式
※document_it就是一個裝飾器,無論將函式什麼傳入document_it( ),你都可以得到一個新的函式,裡面會包含document_it( )加入的陳述式
※只要在想要裝飾的函式前面添加@decorate name就能取代手動指派裝飾器的方式
※寫一個新的裝飾器,會將結果平方
※同一個函式可以有兩個以上的裝飾器,靠近函式的裝飾器會先執行,最終的結果都一樣,但可以發現過程中有不同的步驟
- 命名空間與範圍
一個名稱可以參考不同的東西,Python程式有各種命名空間,在一段程式中,某個名稱是獨一無二的,但是與其他命名空間中的的同一個名稱無關
※可以在函式裡面取得全域變數的值
※但如果在函式裡面取得全域變數的值,並更改它,會得到錯誤
如果在函式裡面修改它,它會另一個叫做animal的變數,但式只在這個函式裡面,id( )為一個變數獨一無二的值,可以看出兩個animal是不同的
一個animal是位於全域的命名空間,一個animal只位於該函式裡面的命名空間
※要存取全域變數,而不是使用函式內的區域變數,你必須使用 global 關鍵字
- locals() 會回傳區域命名空間中的字典內容
globals()會回傳區域命名空間中的字典內容
※全域命名空間會有全域變數和一些其他的東西
- 在名稱中使用_與__
※在Python中,在名稱的開頭與結尾使用兩個底線(__)是被保留的做法(不能在自己的變數中使用它們)
例如函式獨名稱會被存在系統變數fuction .__name__內,它的文件字串是fuction .__doc__
- 使用try與except來處理錯誤
※當你執行一段可能會在某些情況下發生錯誤的程式時,也許需要使用適當的例外處理程式,來攔截任何可能發生的錯誤
※在try段落內的程式會先執行,如果有錯誤就會發出例外,並且執行except段落內的程式,如果沒有錯誤,except段落就會被跳過
- except exceptiontype as name取得例外物件
※以下範例會先查看IndexError,出現例外就存在變數err裡面,將其他例外存在other裡面,這個範例會印出所有存在other裡面的東西,來知道這個物件裡面有什麼
輸入位置 3 會發出例外IndexError,如果我們對int()函式輸入干擾的two,第二個負責捕捉所有例外的Excepot程式會處理它
- 製作你自己的例外
※例外是一種類別(Class),它是Exception類別的子類別,以下為製作一個叫做UppercaseException的例外
※我們並未在UppercaseException定義任何行為,而是讓它的Exception父類別決定例外出現時要印出什麼東西。也可以查看這個例外物件並印出它
- 練習題
- 將7這個值指派給guess_me,使用條件測試式,在guess_me<7、=7、>7時印出不同字串
- 將7這個值指派給guess_me,將1這個值指派給start,寫一個while迴圈來比較兩個的大小,根據結果印出不同字串,每次迴圈結尾遞增start。在start大於guess_me時離開迴圈。
- 使用一個for迴圈來印出串列[3,2,1,0]的值
- 使用一個串列生成式來製作一個range(10)內的偶數串列
- 使用一個字典生成式來製作字典squares,使用range(10)來回傳鍵,使用每個鍵的平方作為值
- 使用一個集合生成式,以range(10)內的奇數來製作odd集合
- 使用產生器生成式來回傳字串'Got',與range(10)內的一個數字,使用for迴圈來迭代它
- 定義一個命名為good()的函式,讓他回傳串列
- 定義一個名為get_odds()的產生器函式,讓他回傳range(10)的奇數,使用一個for迴圈來印出它回傳的第三個值
※內建函數 (function) enumerate() ,回傳以參數 (parameter) iterable 與連續整數配對的 enumerate 物件, start 為整數的起始值,預設為 0
※產生器要用yield來回傳
- 定義一個名為test的裝飾器,如果有一個函式被呼叫時,印出'start',當那函式結束時印出'end'
※要在裝飾器裡面寫一個內部函式,並且把外部的函式(要被修改的函式)代入進裝飾器裡
- 定義一個名為OopsException的例外,發出這個例外看看有什麼事情發生接著寫一段程式來捕捉這個例外,並印出'Caught an oops'
- 用zip()來製作一個稱為movies的字典,讓它配對這些串列:titles=['ivanpotato很帥','ivanpotato超帥'],plots=['clover很正','clover超正']
※用zip配對tuple,再將它們傳入dict,變成字典