2016-07-14 21 views
2

我剛纔看到下面的代碼:以發電機出了上下文管理的

from __future__ import print_function 
from future_builtins import map # generator 

with open('test.txt', 'r') as f: 
    linegen = map(str.strip, f) 

# file handle should be closed here 

for line in linegen: 
    # using the generator now 
    print(line) 

在這種情況下會發生什麼?上下文管理器是否足夠聰明,知道linegen仍然有一個對文件句柄的引用,以便在上下文剩下時它不會關閉?或者這可能是不安全的?

+0

你有沒有嘗試過? –

+0

它不*可能*不安全,它*不安全;您可以通過嘗試從關閉的文件中讀取來看到引發的異常。 – chepner

+1

這只是看起來不對 –

回答

2

這是Python中的重大更改一個3

你的問題標題(隔空發電機 ...)意味着你正在閱讀它的Python 3代碼。

但聲明

from __future__ import print_function 

意味着它是爲Python 2編寫

在Python 2,map返回一個實際列表 - 所以該代碼是兩個完全安全的,並extrmely明智的(即開文件,讀取所有行,S絆倒他們爲你去,然後關閉文件)

In [2]: with open('README.md','r') as f: 
    ...:  lines = map(str.strip, f) 
    ...:  
In [3]: lines 
Out[3]: 
['ASM', 
'============', 
'', 

在Python 3,同樣的代碼拋出一個異常

In [1]: with open('README.md','r') as f: 
    lines = map(str.strip, f) 
    ...:  
In [2]: lines 
Out[2]: <map at 0x7f4d393c3ac8> 
In [3]: list(lines) 
--------------------------------------------------------------------------- 
ValueError        Traceback (most recent call last) 
<ipython-input-3-2666a44c63b5> in <module>() 
----> 1 list(lines) 

ValueError: I/O operation on closed file. 

如果你想要這個,你需要或者發電機轉換成列表的版本安全的實現

lines = list(map(str.strip, f)) 

或只使用一個列表理解

lines = [l.strip() for l in f] 
+0

'from future_builtins import map'在Python 2中也使'map'成爲一個生成器。我對開放引用與離開上下文的優先級感興趣。看起來上下文勝利,因爲每個人都一直在獲得例外。通過一切手段,隨時關閉這個問題。 – Stefan