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

时间:2016-11-15 22:13:59

标签: python file python-3.x

我正在尝试执行程序遍历目录的任务,依次打开每个文件,并在其他任何内容之前检查特定行。如果该行符合特定条件(即,它与目录中任何其他文件中的此行不匹配),则文件将关闭,程序将移至下一个文件。

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:

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

这是完成此任务的最佳方式吗?如果没有,我怎么能让它发挥作用?

非常感谢。

2 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:1)

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

所以这些行:

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

循环到目前为止已读取的每一行,并计算频率。问题出现在内部for循环中:

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

这里发生的事情是freqs有一组键可能与你到目前为止循环的文件数一样大,并且你循环遍历每个键。因此,当键第一次具有值2时,将关闭当前文件。但是循环继续,所以下次一个键的值为2时,python会尝试关闭该文件,但它已经关闭。

最简单的解决方法是在break之后添加f.close()。但是有更好的方法来构建这个代码。

一种是始终使用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的方式到达那里,但这是我最好的想法。