最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

分析用Python腳本關閉文件操作的機制

 更新時間:2015年06月28日 12:15:56   投稿:goldensun  
這篇文章主要介紹了分析用Python腳本關閉文件操作的機制,作者分Python2.x版本和3.x版本兩種情況進行了闡述,需要的朋友可以參考下

如果不用“with”,那么Python會在何時關閉文件呢?答案是:視情況而定。

Python程序員最初學到的東西里有一點就是可以通過迭代法很容易地遍歷一個打開文件的全文:

f = open('/etc/passwd')
for line in f:
  print(line)

注意上面的代碼具有可行性,因為我們的文件對象“f”是一個迭代器。換句話說,“f“ 知道在一個循環(huán)或者任何其他的迭代上下文中做什么,比如像列表解析。

我的Python課堂上的大多數學生都具有其他編程語言背景,在使用以前所熟悉的語言時,他們總是在完成文件操作時被期望關閉文件。因此,在我向他們介紹了Python文件操作的內容不久后他們問起如何在Python中關閉文件時,我一點都不驚訝。

最簡單的回答就是我們可以通過調用f.close()顯式地關閉文件。一旦我們關閉了文件,該文件對象依然存在,但是我們無法再通過它來讀取文件內容了,而且文件對象返回的可打印內容也表明文件已經被關閉。

>>> f = open('/etc/passwd')
>>> f
<open file '/etc/passwd', mode 'r' at 0x10f023270>
>>> f.read(5)
'##n# '
 
f.close()
>>> f
<closed file '/etc/passwd', mode 'r' at 0x10f023270>
 
f.read(5)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-11-ef8add6ff846> in <module>()
----> 1 f.read(5)
ValueError: I/O operation on closed file

所以是這樣,我在用Python編程的時候,很少明確地對文件調用 “close” 方法。此外,你也很可能不想或不必那樣做。

打開文件的優(yōu)選最佳實踐方式是使用 “with” 語句,就像如下所示:

with open('/etc/passwd') as f:
  for line in f:
    print(line)

“with”語句對 “f” 文件對象調用在Python中稱作“上下文管理器”的方法。也就是說,它指定 “f” 為指向 /etc/passwd 內容的新的文件實例。在 “with” 打開的代碼塊內,文件是打開的,而且可以自由讀取。

然而,一旦Python代碼從 “with” 負責的代碼段退出,文件會自動關閉。試圖在我們退出 “with”代碼塊后從 f 中讀取內容會導致和上文一樣的 ValueError 異常。所以,通過使用 “with”,你避免了顯式地關閉文件的操作。Python 會以一種不那么有 Python 風格的方式在幕后神奇而靜靜地替你關閉文件。

但是你不顯式地關閉文件會怎樣?如果你有點懶,既不使用 “with” 代碼塊也不調用f.close()怎么辦?這時文件會什么時候關閉?何時應該關閉文件?

我之所以問這個,是因為我教了這么多年Python,確信努力教授“with”或上下文管理器的同時又教很多其它的話題超出了學生接受的范圍。在介紹性課程談及 “with” 時,我一般會告訴學生在他們職業(yè)生涯中遇到這個問題時,讓Python去關閉文件就好,不論文件對象的應用計數降為0還是Python退出時。

在我的Python文件操作免費e-mail課程中,我并沒有在所有的解決方案中使用with,想看看如何。結果一些人質疑我,說不使用“with”會向人們展示一種糟糕的實踐方案并且會有數據未寫入磁盤的風險。

我收到了很多關于此話題的郵件,于是我問自己:如果我們沒有顯式地關閉文件或者沒用“with”代碼塊,那么Python會何時關閉文件?也就是說,如果我讓文件自動關閉,那么會發(fā)生什么?

我總是假定當對象的引用計數降為0時,Python會關閉文件,進而垃圾回收機制清理文件對象。當我們讀文件時很難證明或核實這一點,但寫入文件時卻很容易。這是因為當寫入文件時,內容并不會立即刷新到磁盤(除非你向“open”方法的第三個可選參數傳入“False”),只有當文件關閉時才會刷新。

于是我決定做些實驗以便更好地理解Python到底能自動地為我做什么。我的實驗包括打開一個文件、寫入數據、刪除引用和退出Python。我很好奇數據是什么時候會被寫入,如果有的話。

我的實驗是這個樣子:

f = open('/tmp/output', 'w')
f.write('abcn')
f.write('defn')
# check contents of /tmp/output (1)
del(f)
# check contents of /tmp/output (2)
# exit from Python
# check contents of /tmp/output (3)

我在Mac平臺上用Python 2.7.9 做了第一個實驗,報告顯示在階段一文件存在但是是空的,階段二和階段三中文件包含所有的內容。這樣,在CPython 2.7中我最初的直覺似乎是正確的:當一個文件對象被垃圾回收時,它的 __del__ (或者等價的)方法會刷新并關閉文件。而且在我的IPython進程中調用“l(fā)sof”命令顯示文件確實在引用對象移除后被關閉了。

那 Python3 如何呢?我在Mac上 Python 3.4.2 環(huán)境下做了以上的實驗,得到了相同的結果。移除對文件對象最后的引用后會導致文件被刷新并且被關閉。

這對于 Python 2.7 和 3.4 很好。但是在 PyPy 和 Jython下的替代實現會怎樣呢?或許情況會有些不同。

于是我在 PyPy 2.7.8 下做了相同的實驗。而這次,我得到了不同的結果!刪除文件對象的引用后——也就是在階段2,并沒有導致文件內容被刷入磁盤。我不得不假設這和垃圾回收機制的不同或其他在 PyPy 和 CPython中工作機制的不同有關系。但是如果你在 PyPy中運行程序,就絕不要指望僅僅因為文件對象的引用結束,文件就會被刷新和關閉。命令 lsof 顯示直到Python進程退出時文件才會被釋放。

為了好玩,我決定嘗試一下 Jython 2.7b3. 結果Jython 表現出了和PyPy一樣的行為。也就是說,從 Python 退出確實會確保緩存中的數據寫入磁盤。

我重做了這些實驗,但是我把 “abcn”和 “defn”換成了 “abcn”*1000 和“defn”*1000.

在 Python 2.7 的環(huán)境下,“abcn” * 1000 語句執(zhí)行后沒有任何東西寫入。但“defn” * 1000 語句執(zhí)行后,文件包含有4096個字節(jié)——可能代表緩沖區(qū)的大小。調用 del(f) 刪除文件對象的引用導致數據被刷入磁盤和文件關閉,此時文件中共有8000字節(jié)的數據。所以忽略字符串大小的話 Python 2.7 的行為表現基本相同。唯一不同的是如果超出了緩沖區(qū)的大小,那么一些數據將在最后文件關閉數據刷新前寫入磁盤。

換做是Python 3的話,情況就有些不同了。f.write執(zhí)行后沒有任何數據會寫入。但是文件對象引用一旦結束,文件就會刷新并關閉。這可能是緩沖區(qū)很大的緣故。但毫無疑問,刪除文件對象引用會使文件刷新并關閉。

至于 PyPy 和 Jython,對大文件和小文件的操作結果都一樣:文件在 PyPy 或 Jython 進程結束的時候刷新并關閉,而不是在文件對象的引用結束的時候。

為了再次確認,我又使用 “with” 進行了實驗。在所有情況下,我們都能夠輕松的預測文件是何時被刷新和關閉的——就是當退出代碼段,并且上下文管理器在后臺調用合適方法的時候。

換句話說,如果你不使用“with”,那么至少在非常簡單的情形下,你的數據不一定有丟失的危險。然而你還是不能確定數據到底是在文件對象引用結束還是程序退出的時候被保存的。如果你假定因為對文件唯一的引用是一個本地變量所以文件在函數返回時會關閉,那么事實一定會讓你感到吃驚。如果你有多個進程或線程同時對一個文件進行寫操作,那么你真的要非常小心了。

或許這個行為可以更好地定義不就可以在不同的平臺上表現得基本一致了嗎?也許我們甚至可以看看Python規(guī)范的開始,而不是指著CPython說“Yeah,不管版本如何總是對的”。

我依然覺得“with”和上下文管理器很棒。而且我想對于Python新手,理解“with”的工作原理很難。但我還是不得不提醒新手開發(fā)者注意:如果他們決定使用Python的其他可選版本,那么會出現很多不同于CPython的古怪情況而且如果他們不夠小心,甚至會深受其害。

相關文章

  • 解決pyinstaller打包發(fā)布后的exe文件打開控制臺閃退的問題

    解決pyinstaller打包發(fā)布后的exe文件打開控制臺閃退的問題

    今天小編就為大家分享一篇解決pyinstaller打包發(fā)布后的exe文件打開控制臺閃退的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-06-06
  • PyQt5顯示GIF圖片的方法

    PyQt5顯示GIF圖片的方法

    今天小編就為大家分享一篇PyQt5顯示GIF圖片的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-06-06
  • Flaks基礎之在URL中添加變量的實現詳解

    Flaks基礎之在URL中添加變量的實現詳解

    這篇文章主要介紹了在python開發(fā)中,Flaks框架之上在URL鏈接中添加變量的實現方式,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-09-09
  • 詳解Python中os.path與pathlib的用法和性能對比

    詳解Python中os.path與pathlib的用法和性能對比

    pathlib 模塊是在Python3.4版本中首次被引入到標準庫中的,這篇文章主要來和大家介紹一下Python中os.path與pathlib再用法和性能上的區(qū)別,感興趣的可以了解下
    2024-03-03
  • 如何通過Python3和ssl實現加密通信功能

    如何通過Python3和ssl實現加密通信功能

    這篇文章主要介紹了如何通過Python3和ssl實現加密通信功能,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-05-05
  • pandas merge報錯的解決方案

    pandas merge報錯的解決方案

    這篇文章主要介紹了pandas merge報錯的解決方案,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • python實現數字炸彈游戲程序

    python實現數字炸彈游戲程序

    這篇文章主要為大家詳細介紹了python實現數字炸彈游戲程序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-07-07
  • Python順序結構語句詳解

    Python順序結構語句詳解

    這篇文章主要為大家介紹了Python順序結構語句,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-01-01
  • 如何使用 Python 讀取文件和照片的創(chuàng)建日期

    如何使用 Python 讀取文件和照片的創(chuàng)建日期

    這篇文章主要介紹了如何使用 Python 讀取文件和照片的創(chuàng)建日期,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-09-09
  • python?中的jieba分詞庫

    python?中的jieba分詞庫

    這篇文章主要介紹了python中的jieba分詞庫,jieba?庫是優(yōu)秀的中文分詞第三方庫,中文文本需要通過分詞獲得單個的詞語,下面文章的的詳細內容,需要的朋友可以參考一下
    2021-11-11

最新評論

额尔古纳市| 舒城县| 前郭尔| 武乡县| 太康县| 岑溪市| 河东区| 巴林左旗| 临安市| 虞城县| 景洪市| 平塘县| 西乌| 察隅县| 石阡县| 防城港市| 静安区| 杨浦区| 尼勒克县| 鄱阳县| 西乌珠穆沁旗| 河南省| 遂川县| 万全县| 和田市| 昌都县| 宝山区| 错那县| 滁州市| 墨竹工卡县| 岳阳县| 曲沃县| 大新县| 冀州市| 宣恩县| 太保市| 翁源县| 皋兰县| 唐山市| 嘉兴市| 常宁市|