創作內容

7 GP

Context Manager

作者:Yotsuba│2020-05-28 19:19:09│巴幣:62│人氣:358
Context Manager 的中文叫資源管理器

大家應該有在 Python 看過 with ... as 這樣的語法,它就是 Context Manager

比如說 Python 的 File I/O,一般來說寫法可能如下 :


file = open('foo.txt', 'w+')
file.write('bar')
file.close()


執行結果不會有 Output

這段程式碼就是打開一個叫 foo.txt 的檔案,然後寫入字串 bar 並且關檔

大家可以發現到,我們需要做一個「關檔」的動作


沒有關檔會怎樣 ?

首先,我們在撰寫程式語言的時候必須重視記憶體的管理

請求來的物件,當生命週期到了就該銷毀物件,做一個歸還記憶體的動作

即使 Python 不像 C 語言一樣需要時時刻刻注意記憶體管理,但也不能忽略這個議題


再者,程式如果是「不正當」的關閉,可能會造成資料的遺失

所以檔案讀寫完畢,最好的習慣都是馬上關閉檔案

Context Manager 顧名思義就是在幫我們管理資源,參考以下程式碼 :


with open('foo.txt', 'w+') as file:
    file.write('bar')


它和剛才的程式碼做的事情一模一樣,好處在於不用自己管理資源,而且語法更簡潔了

因為 with ... as 的程式區塊結束,file 的資源就會自己被歸還


具體來說,with ... as 在建立資源的時候是呼叫物件的 __enter__ 方法

銷毀的時候呼叫 __exit__ 方法

我們也可以實作一個 File 物件,程式碼如下 :


class File:
    def __init__(self, file, method):
        self.file = open(file, method)
    def __enter__(self):
        return self.file
    def __exit__(self, type, value, traceback):
        self.file.close()


with File('foo.txt', 'w+') as file:
    file.write('bar')


然後別問我 __exit__ 裡面的 type、value、traceback 參數是什麼 ?

我在翻文件的時候看到 「We did not talk about the type, value and traceback
arguments of the __exit__ method .」

所以我也不知道 ...

不過從邏輯上來看用法已經很清楚了,而且一般來說也只需要會使用 with ... as 就足夠了


說了這麼多,Context Manager 具體來說能為爬蟲做些什麼 ?

基本上我常用來讀寫檔案,還有下載二進位檔案,包括圖片、影片等等 ...

上次 Beautiful Soup (下) 有教大家寫到取得圖片連結,但是沒有教如何下載


他確定是一個 .jpg 檔案,這時候就可以下載它,程式碼如下 :


import requests

response = requests.get('https://www.pythonscraping.com/img/gifts/img1.jpg')

with open('img.jpg', 'wb') as file:
    file.write(response.content)


執行完畢就可以看到 img.jpg 了,點擊開來會跟網站上一模一樣

這就是 Context Manager 的一個應用,或者說讀寫檔案的應用

這邊有幾個重點需要注意一下


首先,開檔案的時候要以 wb 模式,也就是二進位寫入模式

詳細可以搜尋 Python Files I/O,因為開檔模式有太多種了

總之 .jpg 檔案是一個二進位,所以要使用二進位模式


再來,寫入的時候是 response 的 content,為什麼是 content ?

如果你去 print response 的 text 或 content,看起來會長得一模一樣

差別在於 text 回傳的是 Unicode,content 回傳的是 Binary,這樣了解了吧 ?

你想寫入 response 的 text 會直接噴 Error

TypeError : a bytes-like object is required, not 'str'


下載檔案的方法不只一種,下次會介紹 urllib3.request 的 urlretrieve 方法

雖然大部分時候使用 Context Manager 即可


延伸閱讀 : urlretrieve
引用網址:https://home.gamer.com.tw/TrackBack.php?sn=4797792
All rights reserved. 版權所有,保留一切權利

相關創作

留言共 1 篇留言

沒人理你
愛你

07-28 20:16

我要留言提醒:您尚未登入,請先登入再留言

7喜歡★happy819tw 可決定是否刪除您的留言,請勿發表違反站規文字。

前一篇:Beautiful So... 後一篇:累 ......

追蹤私訊切換新版閱覽

作品資料夾

yvonne405282024年更新計畫
2024年,每週六小屋都會更新文章,大多是小說和新詩。我是可以週更的人了!看更多我要大聲說昨天21:15


face基於日前微軟官方表示 Internet Explorer 不再支援新的網路標準,可能無法使用新的應用程式來呈現網站內容,在瀏覽器支援度及網站安全性的雙重考量下,為了讓巴友們有更好的使用體驗,巴哈姆特即將於 2019年9月2日 停止支援 Internet Explorer 瀏覽器的頁面呈現和功能。
屆時建議您使用下述瀏覽器來瀏覽巴哈姆特:
。Google Chrome(推薦)
。Mozilla Firefox
。Microsoft Edge(Windows10以上的作業系統版本才可使用)

face我們了解您不想看到廣告的心情⋯ 若您願意支持巴哈姆特永續經營,請將 gamer.com.tw 加入廣告阻擋工具的白名單中,謝謝 !【教學】