10.Python 標準函式庫概覽

10.1.作業系統介面

os 模組提供了數十個與作業系統溝通的函式:

>>>importos>>>os.getcwd()# 回傳目前的工作目錄'C:\\Python313'>>>os.chdir('/server/accesslogs')# 改變目前的工作目錄>>>os.system('mkdir today')# 在系統 shell 中執行 mkdir 指令0

務必使用importos 而非fromosimport*。這將避免因系統不同而有實作差異的os.open() 覆蓋內建函式open()

在使用os 諸如此類大型模組時搭配內建函式dir()help() 是非常有用的:

>>>importos>>>dir(os)<returns a list of all module functions>>>>help(os)<returns an extensive manual page created from the module's docstrings>

對於日常檔案和目錄管理任務,shutil 模組提供了更容易使用的高階介面:

>>>importshutil>>>shutil.copyfile('data.db','archive.db')'archive.db'>>>shutil.move('/build/executables','installdir')'installdir'

10.2.檔案之萬用字元 (File Wildcards)

glob 模組提供了一函式可以從目錄萬用字元中搜尋並產生檔案列表:

>>>importglob>>>glob.glob('*.py')['primes.py', 'random.py', 'quote.py']

10.3.命令列引數

通用工具腳本常需要處理命令列引數。這些引數會以 list(串列)形式存放在sys 模組的argv 屬性中。例如以下demo.py 檔案:

# demo.py 檔案importsysprint(sys.argv)

以下是在命令列運行pythondemo.pyonetwothree 的輸出:

['demo.py','one','two','three']

argparse 模組提供了一種更複雜的機制來處理命令列引數。以下腳本可擷取一個或多個檔案名稱,並可選擇要顯示的行數:

importargparseparser=argparse.ArgumentParser(prog='top',description='Show top lines from each file')parser.add_argument('filenames',nargs='+')parser.add_argument('-l','--lines',type=int,default=10)args=parser.parse_args()print(args)

pythontop.py--lines=5alpha.txtbeta.txt 在命令列執行時,該腳本會將args.lines 設為5,並將args.filenames 設為['alpha.txt','beta.txt']

10.4.錯誤輸出重新導向與程式終止

sys 模組也有stdinstdout,和stderr 等屬性。即使當stdout 被重新導向時,後者stderr 可輸出警告和錯誤訊息:

>>>sys.stderr.write('Warning, log file not found starting a new one\n')Warning, log file not found starting a new one

終止腳本最直接的方式就是利用sys.exit()

10.5.字串樣式比對

re 模組提供正規表示式 (regular expression) 做進階的字串處理。當要處理複雜的比對以及操作時,正規表示式是簡潔且經過最佳化的解決方案:

>>>importre>>>re.findall(r'\bf[a-z]*','which foot or hand fell fastest')['foot', 'fell', 'fastest']>>>re.sub(r'(\b[a-z]+) \1',r'\1','cat in the the hat')'cat in the hat'

當只需要簡單的字串操作時,因為可讀性以及方便除錯,字串本身的 method 是比較建議的:

>>>'tea for too'.replace('too','two')'tea for two'

10.6.數學相關

math 模組提供了 C 函式庫中底層的浮點數運算的函式:

>>>importmath>>>math.cos(math.pi/4)0.70710678118654757>>>math.log(1024,2)10.0

random 模組提供了隨機選擇的工具:

>>>importrandom>>>random.choice(['apple','pear','banana'])'apple'>>>random.sample(range(100),10)# 不重複抽樣[30, 83, 16, 4, 8, 81, 41, 50, 18, 33]>>>random.random()# 區間 [0.0, 1.0) 中的隨機浮點數0.17970987693706186>>>random.randrange(6)# 從 range(6) 中隨機選擇整數4

statistics 模組提供了替數值資料計算基本統計量(包括平均、中位數、變異量數等)的功能:

>>>importstatistics>>>data=[2.75,1.75,1.25,0.25,0.5,1.25,3.5]>>>statistics.mean(data)1.6071428571428572>>>statistics.median(data)1.25>>>statistics.variance(data)1.3720238095238095

SciPy 專案 <https://scipy.org> 上也有許多數值計算相關的模組。

10.7.網路存取

Python 中有許多存取網路以及處理網路協定。最簡單的兩個例子包括urllib.request 模組可以從網址抓取資料以及smtplib 可以用來寄郵件:

>>>fromurllib.requestimporturlopen>>>withurlopen('http://worldtimeapi.org/api/timezone/etc/UTC.txt')asresponse:...forlineinresponse:...line=line.decode()# 將 bytes 轉換為 str...ifline.startswith('datetime'):...print(line.rstrip())# 移除最後面的換行符號...datetime: 2022-01-01T01:36:47.689215+00:00>>>importsmtplib>>>server=smtplib.SMTP('localhost')>>>server.sendmail('soothsayer@example.org','jcaesar@example.org',..."""To: jcaesar@example.org...From: soothsayer@example.org......Beware the Ides of March....""")>>>server.quit()

(注意第二個例子中需要在本地端執行一個郵件伺服器。)

10.8.日期與時間

datetime 模組提供許多 class 可以操作日期以及時間,從簡單從複雜都有。模組支援日期與時間的運算,而實作的重點是有效率的成員擷取以達到輸出格式化以及操作。模組也提供支援時區換算的類別。

>>># 能夠輕易建立與格式化>>>fromdatetimeimportdate>>>now=date.today()>>>nowdatetime.date(2003, 12, 2)>>>now.strftime("%m-%d-%y.%d %b %Y is a %A on the%d day of %B.")'12-02-03. 02 Dec 2003 is a Tuesday on the 02 day of December.'>>># 支援運算>>>birthday=date(1964,7,31)>>>age=now-birthday>>>age.days14368

10.9.資料壓縮

常見的解壓縮以及壓縮格式都有直接支援的模組。包括:zlibgzipbz2lzmazipfile 以及tarfile

>>>importzlib>>>s=b'witch which has which witches wrist watch'>>>len(s)41>>>t=zlib.compress(s)>>>len(t)37>>>zlib.decompress(t)b'witch which has which witches wrist watch'>>>zlib.crc32(s)226805979

10.10.效能量測

有一些 Python 使用者很想了解同個問題的不同實作方法的效能差異。Python 提供了評估效能差異的工具。

舉例來說,有人可能會試著用 tuple 的打包機制來交換引數代替傳統的方式。timeit 模組可以迅速地展示效能的進步:

>>>fromtimeitimportTimer>>>Timer('t=a; a=b; b=t','a=1; b=2').timeit()0.57535828626024577>>>Timer('a,b = b,a','a=1; b=2').timeit()0.54962537085770791

相對於timeit 模組提供這麼細的粒度,profile 模組以及pstats 模組則提供了一些在大型的程式碼識別時間使用上關鍵的區塊 (time critical section) 的工具。

10.11.品質控管

達到高品質軟體的一個方法,是在開發時對每個函式寫測試,以及在開發過程中要不斷地跑這些測試。

doctest 模組提供了一個工具,掃描模組並根據程式中內嵌的文件字串執行測試。撰寫測試如同簡單地將它的呼叫及輸出結果剪下並貼上到文件字串中。透過提供範例給使用者,它強化了說明文件,並允許 doctest 模組確認程式碼的結果與說明文件一致:

defaverage(values):"""計算數字串列的算術平均數。    >>> print(average([20, 30, 70]))    40.0    """returnsum(values)/len(values)importdoctestdoctest.testmod()# 自動驗證內嵌的測試

unittest 模組不像doctest 模組這般容易,但是它讓你可以在另外一個檔案裡撰寫更完整的測試集:

importunittestclassTestStatisticalFunctions(unittest.TestCase):deftest_average(self):self.assertEqual(average([20,30,70]),40.0)self.assertEqual(round(average([1,5,7]),1),4.3)withself.assertRaises(ZeroDivisionError):average([])withself.assertRaises(TypeError):average(20,30,70)unittest.main()# 從命令列呼叫會執行所有測試

10.12.標準模組庫

"Batteries included" 是 Python 的設計哲學。這個理念可以透過使用它的大型套件,感受複雜與強大的功能,來得到印證。例如:

  • 使用xmlrpc.clientxmlrpc.server 模組使實作遠端程序呼叫變得更為容易。即使模組名稱裡有 XML,使用者並不需要直接操作 XML 檔案或事先具備相關知識。

  • 函式庫email 套件用來管理 MIME 和其他RFC 2822 相關電子郵件訊息的文件。相異於smtplibpoplib 這些實際用來發送與接收訊息的模組,email 套件擁有更完整的工具集,可用於建立與解碼複雜訊息結構(包含附件檔案)以及實作編碼與標頭協定。

  • json 套件對 JSON 資料交換格式的剖析,提供強大的支援。csv 模組則提供直接讀寫 CSV(以逗號分隔值的檔案格式,通常資料庫和電子表格都有支援)。xml.etree.ElementTreexml.domxml.sax 套件則支援 XML 的處理。綜觀所有,這些模組和套件都簡化了 Python 應用程式與其他工具之間的資料交換。

  • sqllite3 模組是 SQLite 資料庫函式庫的一層包裝,提供一個具持久性的資料庫,可以使用稍微非標準的 SQL 語法來對它進行更新與存取。

  • 有數種支援國際化的模組,包括gettextlocalecodecs 等套件。