Python 應用範例集
這裡示範 Python 內建函式 (Built-in Functions, BIF),在《基礎範例集》已示範過 input() print() type() int() float() hex() oct() bin() str() chr() ord() ascii() bool() abs() complex() divmod() pow() round() range() enumerate() help()
,所以這裡只示範剩下的函式。
對講究簡約的 Python 來說,指令盡量簡單,再靠內建函式加強功能,所以內建函式的重要性就跟指令一樣,是完成基本任務時不可或缺的。
Python 將完成基本任務的功能寫成內建函式,直接呼叫使用。進階任務則寫成標準模組,需要時才載入使用。可見學習 Python 程式設計,首先學語法指令,接著學內建函式,然後學標準模組,照這順序學、或者三管齊下,很快就能掌握 Python 的威力,成為能解決大大小小問題的程式設計高手!
會用模組的話,你能靠別人解決許多特定問題,會內建函式的話,你能憑自己解決大大小小的問題。
bytes
在 Python 你可以直接寫出位元組資料,以 b 開頭,後面用 ASCII 表示法的字串,例如:
b'ABC' | 字串 ABC |
b'123' | 字串 123 |
b'{' | 整數 123 |
b'\x0f' | 整數 15 |
不過,除非你把 ASCII 表背下來,知道整數的 123 要寫成 { 字元,不然還是沒辦法手寫位元組資料,所以要借助內建函式來轉換~
bytes()
使用 bytes()
可以產生位元組的資料。
bytearray()
bytes 是不可變的,所以想修改位元組資料的話,建議改用 bytearray 物件,它會暫存一些位元組資料,修改完再轉為 bytes 資料。
bytearray 和 bytes 支援 str 的操作方法,所以我們能在位元組的型態操作字串:
你可能會想說,誰會吃飽沒事這樣操作字串?的確,平常不建議這樣做。通常從二進制檔案讀取到字串時,因為是位元組型態的字串,才適合這樣做。
memoryview()
只檢視位元組資料的話,可以考慮用 memoryview()
,它是唯讀的,操作方式很像陣列:
bytes 轉 int 或 str
str
即 string(字串)。
雖然可用 str() 產生字串,但通常直接使用 '
或 "
引號,要轉其它資料為字串時才用函式。
在 Python 沒有字元(char; character),只有長度為 1 的字串,所以用單引號或雙引號括起來的文字,地位是一樣的。由於單引號不用按 Shift,比較好打出來,我個人偏好單引號。PEP 8 Style Guide for Python Code 也沒指定哪一種較好,只要求保持一致,遇到要用 \ 字元顯示單引號或雙引號時,才混用單引號和雙引號,避免使用較難閱讀的 \ 字元。三引號的話,PEP 257 Docstring Conventions 建議使用雙引號。
Example 1
Example 2
Example 3
Example 4
Example 5
Example 7
tuple
基本用法
tuple 像前面章節「陣列」看到的 list 一樣,是照順序排列資料的串列,但無法增刪資料,所以也幾乎沒有可操作的功能:
只有一筆資料,卻想寫成 tuple 的話,必須在資料後面加上 ,
符號,不然直譯器會認為這是一筆 int 或 str:
與 list 的區別:tuple 本身就是資料,而不是由資料組成的結構。
從資料的角度來區分,list 是無限串列,tuple 是有限串列,但這不是 Python 引進的原因。是為了讓群集 item1, item2, ..
能像字串 "abc"
一樣直接下語法給指令或函式,而不是每次都用 [] 包成串列,才引進了 tuple。像可變參數或資料交換都是 tuple 的妙用~
所以使用 tuple 時,不要用 list 資料結構的角度去看它,tuple 不是將連續幾筆資料分散開來的結構,而是反過來,將分散開來的結構變成一筆連續的資料。舉例來說,與其想成 tuple 是不可變動的 list,不如想成 list 是用 tuple 資料組成的。
雖然實作上 tuple 跟 list 明明都是集合物件,但意義上 tuple 是跟 str 同等級的「基本資料」,而不是跟 list 同等級的「集合物件」。
list
在「陣列」的範例,已經看過 list 的用法,接下來補充其它用法。
Example 2
Example 3
set
集合(set)是種「元素不會重複」的資料結構,且 Python 的 set 並不照資料先後順序排列,由於不知道資料的位置,也不需要 get(index) 或 [index],想取得 set 的資料就是迭代。
想建立空集合的話,只能用 set()
,不能用 {}。
使用 remove(資料)
和 clear()
可以刪除資料,有趣的還有用 pop()
隨機刪除一筆資料。需要過濾重複資料,並且從資料中隨機挑選不重複資料時,用 set 和 pop() 會省事很多。
每次執行結果不太一樣,我的情形是:
dict
指 dictionary(字典),是種鍵值對的資料結構。新增資料時,名稱已經存在的話,會取代舊的資料。
Example 1
dict 物件可用如下方式操作資料:
clear()
copy()
fromkeys(iterable [,value])
get(key [,default])
items()
keys()
pop(key [,default])
popitem()
setdefault(key [,default])
update([other])
values()
其中刪除資料的部分,主要還是用 del
指令,需要傳回刪除的資料才用 pop()。
處理可迭代資料
filter
frozenset
sorted、reversed
zip
處理物件與變數
與處理物件和檢視變數相關的內建函式有:
callable(object)
classmethod(function)
dir([object])
delattr(object, name)
getattr(object, name[, default])
globals()
hasattr(object, name)
hash(object)
id(object)
isinstance(object, classinfo)
issubclass(class, classinfo)
locals()
object()
property(fget=None, fset=None, fdel=None, doc=None)
repr(object)
setattr(object, name, value)
staticmethod(function)
super([type[, object-or-type]])
vars([object])
__import__(name, globals=None, locals=None, fromlist=(), level=0)
沒興趣,以後再寫~
處理算式
Python 程式可以寫在純文字文件,無須編譯就能直接執行,但純文字文件不就是一種字串的格式嗎?換句話說,如果某個字串很像程式碼,是否可以送給 Python 執行?答案是可以的!先用 compile()
把字串編譯成 Python 程式,再用 exec()
執行。如果只是單純的算式,還可用 eval()
直接計算出結果,好嵌入 Python 的語法中使用。
編譯寫成字串的 Python 程式並執行
格式化數字
使用 format()
可將數值格式化成你想要的樣式,例如想要每三位數標上逗號的 123,456,789 整數,或者只取小數 2 位的浮點數。不過,格式化出來的是字串,無法拿來與數值進行數學運算。
format() 第一個參數是數值,第二個參數是格式化的型式。格式化型式的語法:
填充字元 填充字元的位置 + 長度 , .小數位數 數字型態
填充字元表示數字不夠長度時,自動填上字元,例如 **123,你可以任意決定要用哪個字元來填充,但不能是字串。位置有 > < ^
左、右、中三種。
+
表示啟用正負號,,
表示每三位數加上逗號。要注意的是,這些符號都算在長度裡面,例如 +123,456.789 長度是 12。這也是為何不叫「位數」而叫「長度」的原因。
數的型態有 b c d e E f g G n o s x X %
。
數字型態
讀寫檔案
Python 讀寫檔案很簡單,一律用內建函式 open()
傳回檔案物件,再對物件操作 write()
寫入資料、read()
讀取資料、close()
關閉檔案即可:
open() 第二個參數是讀寫模式,有四種讀寫動作:
r read
w write
a append
x exclusive
一個搭配選項:
+ update
兩種資料模式:
b binary
t text
除了範例介紹的兩種寫法,其它常用的寫法如下:
想追加資料到文件的話,用 'a'。
想建立新的可讀寫檔案,用 'w+'。
想開啟舊的可讀寫檔案,且寫入的資料不想覆蓋舊的資料,用 'a+'。
想開啟舊的可讀寫檔案,且要讓新寫入的資料要覆蓋檔案的舊資料,用 'r+'。
'r' 和 't' 是預設,因此可省略。但 'rb' 的話就不是預設的 'rt' 了,必須寫出來。
讀寫純文字文件
上面寫法在檔案操作失敗時,不保證會執行 f.close() 關閉檔案,所以建議用自動關閉檔案的寫法:
過去 Python 2 會用 try.. finally.. 的寫法保證關閉檔案,但自從 Python 3 引進 with.. as.. 後,已不建議這樣寫程式。
以隨機存取結構讀寫檔案
這是一種可以在文件中指定位置來讀寫資料的結構:
對比的是循序存取結構,一筆一筆或一行一行照順序讀寫資料。
如果需要隨時隨地針對某筆資料做存取,隨機存取結構檔案是很好用的設計。
以二進制資料讀寫檔案
對訴求簡約的 Python 來說,想保存資料的話,盡量用純文字文件,以二進制資料讀寫檔案屬於進階程式設計。退而求其次,也應該採用隨機存取結構讀寫檔案。只有不得不的情況,才改用二進制檔案,否則只是自討沒趣。二進制是用在檔案結構的,不是用在資料保存。
複製二進制檔案
首先複製圖片,練習看看 'b' 參數的用處:
這只是練習,Python 內建複製檔案的模組了,平常不是這樣寫程式。
讀寫二進制檔案
動態型別的 Python 資料型態不多,要將資料轉為二進制是瑣碎的工作,所以藉由 struct 模組代勞:
以這種方式寫入的檔案,會是真正的二進制檔案,不是純文字文件。
以二進制格式讀寫純文字文件
這種程式不常見,既然是純文字文件,卻使用二進制的方式去讀寫資料,根本自找麻煩:
要手動處理 \r\n 換行1,或者載入的模組要求以 Python 的二進制字串格式處理資料時,才會這樣處理純文字文件。
breakpoint
breakpoint()
相當於 import pdb; pdb.set_trace()
的程式寫法,用來呼叫除錯器。除錯器的操作方式,請見 pdb 模組的介紹。