我有30个文本文件,每个文件有30行。 出于某种原因,我需要编写一个打开文件1的脚本,打印文件1的第1行,关闭它,打开文件2,打印文件2的第2行,关闭它,依此类推。我试过这个:
import glob
files = glob.glob('/Users/path/to/*/files.txt')
for file in files:
i = 0
while i < 30:
with open(file,'r') as f:
for index, line in enumerate(f):
if index == i:
print(line)
i += 1
f.close()
continue
显然,我收到了以下错误:
ValueError:关闭文件的I / O操作。
因为f.close()的事情。如何在只读取所需的行之后从文件移动到下一个文件?
答案 0 :(得分:6)
首先,回答问题,如评论中所述,您的主要问题是您关闭文件然后尝试继续迭代它。有罪的代码:
for index, line in enumerate(f): # <-- Reads
if index == i:
print(line)
i += 1
f.close() # <-- Closes when you get a hit
# But loop is not terminated, so you'll loop again
最简单的解决方法是仅break
而不是显式关闭,因为您的with
语句已经保证在退出块时确定性关闭:
for index, line in enumerate(f):
if index == i:
print(line)
i += 1
break
但是因为这很有趣,所以完成同样的任务需要大量清理代码:
import glob
from itertools import islice
# May as well use iglob since we'll stop processing at 30 files anyway
files = glob.iglob('/Users/path/to/*/files.txt')
# Stop after no more than 30 files, use enumerate to track file num
for i, file in enumerate(islice(files, 30)):
with open(file,'r') as f:
# Skip the first i lines of the file, then print the next line
print(next(islice(f, i, None)))
答案 1 :(得分:2)
您可以使用linecache
模块获取所需的线路并为您节省很多麻烦:
import glob
import linecache
line = 1
for file in glob.glob('/Users/path/to/*/files.txt'):
print(linecache.getline(file, line))
line += 1
if line > 30: # if you really need to limit it to only 30
break
答案 2 :(得分:0)
我觉得这样的事情就是你想要的:
import glob
files = glob.glob('/Users/path/to/*/files.txt')
for file in files:
i = 0
while i < 30:
with open(file,'r') as f:
for index, line in enumerate(f):
if index == i:
print(line)
i += 1
break
f.close()
目前,您正在for循环中间关闭文件,然后尝试再次读取它。因此,如果您只在关闭for循环后关闭文件,那么它应该没问题。
答案 3 :(得分:0)
将您的工作分成更简单的步骤,直到最后一步是微不足道的。使用功能。
请记住,文件对象可用作一系列行。
def nth(n, sequence):
for position, item in enumerate(sequence):
if position == n:
return item
return None # if the sequence ended before position n
def printNthLines(glob_pattern)
# Note: sort file names; glob guarantees no order.
filenames = sorted(glob.glob(glob_pattern))
for position, filename in enumerate(filenames):
with open(filename) as f:
line = nth(position, f) # Pick the n-th line.
if line is not None:
print(line)
# IDK what to do if there's no n-th line in n-th file
printNthLines('path/to/*/file.txt')
显然我们将第n个文件扫描到第n行,但这是不可避免的,没有办法直接进入明文文件中的第n行。