繁体   English   中英

Python-如果符合条件则关闭文件

[英]Python - closing a file if it meets a condition

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

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”)',但是这样做有些奇怪,因为当我尝试通过此方法打印第一行时,它会在疯狂的循环中将其发送并多次打印该行。

这是完成此任务的最佳方法吗? 如果没有,我如何使它工作?

非常感谢。

不要有条件地关闭文件。 对打开的文件执行所需的操作,然后最后将其关闭。 使用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循环中:

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

我强烈怀疑有更高效,更Python化的方法可以到达那里,但这是我的最佳想法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM