在這個問題上「Generating an MD5 checksum of a file」,我有這樣的代碼:可以參考依靠關閉Python中的文件嗎?
import hashlib
def hashfile(afile, hasher, blocksize=65536):
buf = afile.read(blocksize)
while len(buf) > 0:
hasher.update(buf)
buf = afile.read(blocksize)
return hasher.digest()
[(fname, hashfile(open(fname, 'rb'), hashlib.sha256())) for fname in fnamelst]
我被批評爲打開列表理解的內部文件,以及一個人認爲,如果我有足夠長的名單我將耗盡打開文件句柄。接口顯着降低了hashfile
的靈活性,並建議使用散列文件獲取文件名參數並使用with
。
是否有必要?我真的做錯了什麼嗎?
測試出這個代碼:
#!/usr/bin/python3
import sys
from pprint import pprint # Pretty printing
class HereAndGone(object):
def __init__(self, i):
print("%d %x -> coming into existence." % (i, id(self)),
file=sys.stderr)
self.i_ = i
def __del__(self):
print("%d %x <- going away now." % (self.i_, id(self)),
file=sys.stderr)
def do_nothing(hag):
return id(hag)
l = [(i, do_nothing(HereAndGone(i))) for i in range(0, 10)]
pprint(l)
結果輸出:
0 7f0346decef0 -> coming into existence.
0 7f0346decef0 <- going away now.
1 7f0346decef0 -> coming into existence.
1 7f0346decef0 <- going away now.
2 7f0346decef0 -> coming into existence.
2 7f0346decef0 <- going away now.
3 7f0346decef0 -> coming into existence.
3 7f0346decef0 <- going away now.
4 7f0346decef0 -> coming into existence.
4 7f0346decef0 <- going away now.
5 7f0346decef0 -> coming into existence.
5 7f0346decef0 <- going away now.
6 7f0346decef0 -> coming into existence.
6 7f0346decef0 <- going away now.
7 7f0346decef0 -> coming into existence.
7 7f0346decef0 <- going away now.
8 7f0346decef0 -> coming into existence.
8 7f0346decef0 <- going away now.
9 7f0346decef0 -> coming into existence.
9 7f0346decef0 <- going away now.
[(0, 139652050636528),
(1, 139652050636528),
(2, 139652050636528),
(3, 139652050636528),
(4, 139652050636528),
(5, 139652050636528),
(6, 139652050636528),
(7, 139652050636528),
(8, 139652050636528),
(9, 139652050636528)]
很明顯,正在創建的列表理解的每個元素構成破壞每個HereAndGone
對象。只要沒有引用它,Python引用計數就會釋放該對象,這會在計算該列表元素的值後立即發生。
當然,也許一些其他的Python實現不這樣做。 Python實現需要做某種形式的引用計數嗎?從gc
模塊的文檔看來,引用計數是該語言的核心功能。
而且,如果我確實做錯了,你會如何建議我重新編寫它以保持列表理解的簡潔明瞭,以及可以像文件一樣讀取的任何接口的靈活性?
「Python實現需要做某種形式的引用計數嗎?」 - 沒有。 – user2357112
「它似乎從gc模塊的文檔中看起來像引用計數是該語言的核心功能。」 - 大多數gc模塊,尤其是關於關閉的部分,應被視爲可選功能。 – user2357112
修改'hashfile',以便獲取文件名並處理打開和關閉文件本身。一般來說,使用系統的內存管理來管理其他資源是一個糟糕的主意。 – tfb