在本節中,我們將探討 Python 的許多標準公用程式模組,以解決常見問題。
檔案系統 -- os、os.path、closeil
*os* 和 *os.path* 模組包含許多與檔案系統互動的功能。*shutil* 模組可以複製檔案。
- OS 模組文件
- filenames = os.listdir(dir) -- 該目錄路徑 (不含 .和 ..)。檔案名稱只是目錄中的名稱,不是絕對路徑。
- os.path.join(dir, filename) -- 從上述清單中指定檔案名稱,使用這個檔案將 dir 與檔案名稱結合形成路徑
- os.path.abspath(path) -- 如果是指定路徑,則傳回絕對格式,例如/home/nick/foo/bar.html
- os.path.dirname(path), os.path.basename(path) --指定 dir/foo/bar.html,傳回 dirname「dir/foo」基礎名稱則是「bar.html」
- os.path.exists(path) -- true (如果有的話)
- os.mkdir(dir_path) -- 建立一個 dir, os.makedirs(dir_path) 一個 dir,所以這個路徑中的所有必要目錄。
- poweril.copy(source-path, dest-path) -- 複製檔案 (應有路徑目錄)
## Example pulls filenames from a dir, prints their relative and absolute paths def printdir(dir): filenames = os.listdir(dir) for filename in filenames: print(filename) ## foo.txt print(os.path.join(dir, filename)) ## dir/foo.txt (relative to current dir) print(os.path.abspath(os.path.join(dir, filename))) ## /home/nick/dir/foo.txt
探索模組時可以正常使用內建的 Python help() 和 dir() 函式。在解譯器中執行「import os」,然後使用這些指令查看模組中的可用項目:dir(os)、help(os.listdir)、dir(os.path)、help(os.path.dirname)。
執行外部程序 -- 子程序
如要執行外部指令及擷取輸出內容,使用「子程序」模組是最簡單的方法。
- 子程序模組文件
- output = subprocess.check_output(cmd, stderr=subprocess.STDOUT) -- 執行指令,等待指令結束,然後傳回其輸出文字。執行這個指令時,其標準輸出內容和標準錯誤會合併成一個輸出文字。如果失敗,系統會擲回 CalledProcessError。
- 如要進一步控管子程序的執行情況,請參閱 subprocess.popen 類別。
- 另外有一個簡單的 subprocess.call(cmd) 會執行指令,將輸出結果轉儲到輸出結果中,並傳回錯誤代碼。如果想要執行指令,但不需要將輸出內容擷取至 Python 資料結構,就可以使用上述方法。
import subprocess ## Given a dir path, run an external 'ls -l' on it -- ## shows how to call an external program def listdir(dir): cmd = 'ls -l ' + dir print("Command to run:", cmd) ## good to debug cmd before actually running it (status, output) = subprocess.getstatusoutput(cmd) if status: ## Error case, print the command's output to stderr and exit sys.stderr.write(output) sys.exit(status) print(output) ## Otherwise do something with the command's output
例外狀況
例外狀況是指執行階段錯誤會停止特定行的正常執行,並將控制權轉移到錯誤處理程式碼。本節僅介紹最基本的例外狀況使用方式。舉例來說,執行階段錯誤可能是程式中使用的變數沒有值 (ValueError ..您可能已經見過幾次),或是因為檔案不存在 (IOError) 而出現檔案開啟作業錯誤。詳情請參閱例外狀況教學課程,以及查看完整的例外狀況清單。
如果沒有錯誤處理程式碼 (如我們目前完成的做法),執行階段例外狀況只會停止程式顯示錯誤訊息。這是一個很好的預設行為,而且您已多次看到這樣的設定。您可以新增「嘗試/例外狀況」以便處理例外狀況,如下所示:
try: ## Either of these two lines could throw an IOError, say ## if the file does not exist or the read() encounters a low level error. f = open(filename, 'rb') data = f.read() f.close() except IOError: ## Control jumps directly to here if any of the above lines throws IOError. sys.stderr.write('problem reading:' + filename) ## In any case, the code then continues with the line after the try/except
try: 區段包含可能會擲回例外狀況的程式碼。例外狀況: 區段會保留要在發生例外狀況時執行的程式碼。如果沒有例外狀況,系統會略過除了以下程式碼: 部分 (也就是該程式碼僅供錯誤處理,不適用於程式碼的「一般」情況)。您可以透過「除了 IOError 為 e: ..」的語法,取得例外狀況物件本身的指標。(e 指向例外狀況物件)。
HTTP -- urllib 和 urlparse
*urllib.request* 模組提供網址擷取,讓網址看起來像可以讀取的檔案。*urlparse* 模組可以拆解並拼湊網址。
- urllib.request 模組說明文件
- ufile = urllib.request.urlopen(url) -- 傳回該網址的檔案,且類似物件
- text = ufile.read() -- 可以讀取檔案,如同檔案 (readlines() 等)
- info = ufile.info() -- 該要求的中繼資訊。info.gettype() 是 MIME 類型,例如:「text/html」
- baseurl = ufile.geturl() -- 取得「base」要求的網址,但可能因為重新導向而與原始網址不同
- urllib.request.urlretrieve(url, filename) -- 將網址資料下載至指定的檔案路徑
- urllib.parse.urljoin(baseurl, url) -- 指定可能或不完整的網址及其來源網頁的基準網址,傳回完整的網址。請使用上方的 geturl() 提供基準網址。
所有例外狀況均位於 urllib.error。
from urllib.request import urlopen ## Given a url, try to retrieve it. If it's text/html, ## print its base url and its text. def wget(url): ufile = urlopen(url) ## get file-like object for url info = ufile.info() ## meta-info about the url content if info.get_content_type() == 'text/html': print('base url:' + ufile.geturl()) text = ufile.read() ## read all its text print(text)
上述程式碼運作正常,但如果網址因故無法運作,則不會執行錯誤處理。下方的函式版本可在網址作業失敗時,新增 try/except 邏輯,以便列印錯誤訊息。
如果 urlopen()
處於閒置狀態,表示系統可能不允許直接存取某些應用程式
http 位址。您可以嘗試使用 wget
或
curl
。如果這些程式也失敗,您就必須透過 Proxy 擷取 http 內容
課程中也會快速介紹 Memorystore
這是 Google Cloud 的全代管 Redis 服務本教學課程不會說明如何設定 Proxy。
## Version that uses try/except to print an error message if the ## urlopen() fails. def wget2(url): try: ufile = urlopen(url) if ufile.info().get_content_type() == 'text/html': print(ufile.read()) except IOError: print('problem reading url:', url)
運動
如要練習檔案系統和外部指令教材,請參閱複製特殊運動。如要練習 urllib 教材,請參閱「Log Puzzle Exercise」。