Python - 如果文件满足条件,则关闭文件

问题描述:

我想要执行一个任务,其中程序要经过一个目录,轮流打开每个文件,并在任何其他事项之前检查特定行。如果该行符合特定条件(即,它不匹配目录中任何其他文件中的此行),则文件关闭,程序将移至下一个文件。Python - 如果文件满足条件,则关闭文件

aps = [] 

import os 
for filename in os.listdir("C:\..."): 
    f = open(filename,"r") 
    (f.readline()) 
    (f.readline()) 
    ap = (f.readline()) 
    ap = ap.rstrip("\n") 
    aps.append(ap) 
    freqs = {} 
    for ap in aps: 
     freqs[ap] = freqs.get(ap, 0) + 1 
    for k, v in freqs.items(): 
     if v == 2: 
      f.close() 
     else: 

对于“别人:”我最初试图“f.seek(0)”,但得到的Python的错误无​​法与一个封闭的文件工作。然后我再次尝试'f = open(filename,“r”)',但是这样做有点奇怪,因为当我试图通过这种方法打印第一行时,它会在疯狂的循环中发送它并多次打印该行。

这是完成此任务的最佳方式吗?如果不是,我怎么才能使它工作?

非常感谢。

+0

'f.close'后面'else'分支的用途是什么?你还需要从文件中读取吗? – sal

+0

您应该在关闭文件后添加一个“break”,以便它不会循环。 –

请勿有条件地关闭文件。做你需要做的与打开的文件,然后在最后关闭它。随着with构造文件将自动关闭:

for filename in os.listdir(path): 
    with open(filename) as f: 
     # do processing here 
     if positive_condition: 
      # do more processing 

这就是为什么你的代码失败。您在外部for循环之外初始化aps列表,以便它将包含循环的所有文件中的指定行。然后您的freqs字典重置为您打开的每个文件为空。

那么这些行:

for ap in aps: 
    freqs[ap] = freqs.get(ap, 0) + 1 

环比已到目前为止读取,并计算频率的每一行。这个问题是在内部进行循环:

for k, v in freqs.items(): 
    if v == 2: 
     f.close() 

这里会发生什么事是freqs有一组按键可能一样大,你已经挂绕到目前为止文件的数量,而你是通过每个键循环。因此,第一次键值为2时,当前文件被关闭。但是循环继续,所以下一次键值为2时,python会尝试关闭文件,但它已经关闭。

最简单的修复方法是在f.close()之后添加break。但是有更好的方法来构造这些代码。

一个是总是用with命令打开一个文件,除非你有充分的理由不这样做。所以:

with open(filename,"r") as f: 
    #code 

这样,当你完成它的文件将自动关闭。

我假设您循环遍历文件的顺序并不重要,并且您希望频率测试包括所有文件,而不仅仅是迄今为止打开的文件。在这种情况下,可能会更容易循环两次,一次用于组合频率字典,另一次用于对要满足频率要求的文件做任何想做的事情。

aps = [] 
freqs = {} 
# First loop to read the important line from all files 
for filename in os.listdir("C:\..."): 
    with open(filename,"r") as f: 
     f.readline() 
     f.readline() 
     ap = f.readline().rstrip("\n") 
     aps.append(ap) 
# Populate the dictionary 
for ap in aps: 
    freqs[ap] = freqs.get(ap, 0) + 1 
# Second loop to handle the important cases 
for filename in os.listdir("C:\..."): 
    with open(filename,"r") as f: 
     f.readline() 
     f.readline() 
     ap = f.readline().rstrip("\n") 
     if freqs[ap] != 2: 
      #do whatever 

我强烈怀疑有更高效和pythonic方式到达那里,但这是我最好的想法。