我希望我能正确地解决这个问题。我试图强迫自己成为一个更好的程序员。更好,我的意思是效率。我想编写一个程序来识别目录中的文件并读取每个文件以便进一步处理。经过一番洗牌,我得到了这个:
for file in os.listdir(dir):
y=open(dir+'\\'+file,'r').readlines()
for line in y:
pass
y.close()
因为y是一个列表,所以我得到一个AttributeError就不足为奇了。当我编写代码片段时,我没有想到这一点。
我正在考虑这个问题,我担心我有五个打开的文件(dir指定的目录中有五个文件。
我可以修复代码,使其运行,并在打开文件后显式关闭它们。我很好奇,如果我需要或者如果Python处理在循环的下一次迭代中关闭文件。如果是这样,我只需要写:
for file in os.listdir(dir):
y=open(dir+'\\'+file,'r').readlines()
for line in y:
pass
我猜它(python)确实毫不费力地处理了这个问题。我认为可以处理的原因是我已经更改了y引用的对象/事物。当我开始第二次迭代时,不再有使用readlines方法打开和读取的文件的内存引用。
答案 0 :(得分:11)
Python会在收集垃圾时关闭打开的文件,所以通常你会忘记它 - 特别是在阅读时。
那就是说,如果你想要明确地结束,你可以这样做:
for file in os.listdir(dir):
f = open(dir+'\\'+file,'r')
y = f.readlines()
for line in y:
pass
f.close()
但是,我们可以立即改进这一点,因为在python中你可以直接遍历文件类对象:
for file in os.listdir(dir):
y = open(dir+'\\'+file,'r')
for line in y:
pass
y.close()
最后,在最近的python中,有'with'语句:
for file in os.listdir(dir):
with open(dir+'\\'+file,'r') as y:
for line in y:
pass
当with
块结束时,python将为您关闭文件并进行清理。
(您还可以查看os.path
以获取更多用于操作文件名和目录的pythonic工具)
答案 1 :(得分:3)
不要担心。 Python的垃圾收集器很好,我从来没有关闭文件指针的问题(至少对于读取操作)
如果您确实要明确关闭文件,只需将open()
存储在一个变量中,然后在其上调用readlines()
,例如..
f = open("thefile.txt")
all_lines = f.readlines()
f.close()
或者,您可以使用with
语句,该语句在Python 2.5中添加为from __future__
导入,并在Python 2.6中添加“正确”:
from __future__ import with_statement # for python 2.5, not required for >2.6
with open("thefile.txt") as f:
print f.readlines()
# or
the_file = open("thefile.txt")
with the_file as f:
print f.readlines()
文件将在块结束时自动关闭。
..但是,在你发布的片段中还有其他更重要的事情需要担心,主要是风格。
首先,尽量避免使用字符串连接手动构建路径。 os.path
模块包含许多方法,以更可靠,跨平台的方式执行此操作。
import os
y = open(os.path.join(dir, file), 'r')
此外,您使用的是两个变量名dir
和file
- 两者都是内置函数。 Pylint是一个很好的工具来发现这样的事情,在这种情况下它会发出警告:
[W0622] Redefining built-in 'file'