Python读取文本文件并保持打开状态

时间:2021-04-13 13:31:48

I have a text file that I read in with Python and I then determine the line numbers of lines that contain particular keywords. For some reason, I find that I have to open the file each time I search for a different keyword. I've tried using a with statement to keep the file open, but this does not seem to work.

我有一个用Python读入的文本文件,然后我确定包含特定关键字的行的行号。出于某种原因,我发现每次搜索不同的关键字时都必须打开文件。我已经尝试使用with语句来保持文件打开,但这似乎不起作用。

In the example below, I find the line number of the last line in the file as well as the first line that contains the string 'Results'

在下面的示例中,我找到文件中最后一行的行号以及包含字符串'Results'的第一行

with open(MyFile,'r') as f:
    lastline = sum(1 for line in f)

    for num, line in enumerate(f): 
        if 'Results' in line:
            ResultLine=num   
            break

This successfully does the first operation (determining the last line), but not the latter. If I instead just open the file twice it works:

这成功地完成了第一次操作(确定最后一行),但没有后者。如果我只是打开文件两次它的工作原理:

f=open(MyFile, 'r')
lastline = sum(1 for line in f)

f=open(MyFile, 'r')      
for num, line in enumerate(f): 
    if 'Results' in line:
        ResultLine=num   
        break

Any suggestions as to why I can't keep the file open with my with statement?

有关为什么我不能用我的with语句保持文件打开的任何建议?

Thanks for the help.

谢谢您的帮助。

5 个解决方案

#1


2  

Try doing both tasks together in a single pass over the file:

尝试在文件中一次完成两个任务:

with open(MyFile,'r') as f:
    searching = True
    for num, line in enumerate(f): 
        if searching and 'Results' in line:
            ResultLine=num
            searching = False
    lastline = num

#2


3  

If you want to work with the same file you need to rewind the file pointer. Just do f.seek(0) before your second enumeration

如果要使用同一文件,则需要回退文件指针。在第二次枚举之前,请执行f.seek(0)

However, getting into what your code is actually doing, it can be optimized to do all in the same loop

但是,要了解代码实际执行的操作,可以优化它以在同一个循环中执行所有操作

with open(MyFile,'r') as f:
    lastline = 0
    ResultLine = None

    for num, line in enumerate(f): 
        if not ResultLine and 'Results' in line:
            ResultLine=num

    lastline = num # + 1 if you want a count; this is what you actually get 
                   # in your sample, the count, not the last line index

#3


2  

with open(MyFile,'r') as f:
    lastline = sum(1 for line in f)

    ## The pointer f has reached the end of the file here
    ## Need to reset pointer back to beginning
    f.seek(0)

    for num, line in enumerate(f): 
        if 'Results' in line:
            ResultLine=num   
            break

#4


1  

with creates a contextmanager

与创建上下文管理器

contextmanagers will automatically clean up after them selves when you exit their scope ... (ie close the filehandle)

当你退出范围时,contextmanagers会自动清理它们...(即关闭文件句柄)

this answer only addresses why your filehandle is closed when you exit the with statement

此答案仅解决了退出with语句时关闭文件句柄的原因

see http://preshing.com/20110920/the-python-with-statement-by-example/ for some more info about the with statement and contextmanagers (first link that came up on googling for "file contextmanager")

有关with语句和contextmanagers的更多信息,请参阅http://preshing.com/20110920/the-python-with-statement-by-example/(google搜索“file contextmanager”时出现的第一个链接)

#5


-1  

The problem is that you've effectively read the entire file once already, so when you go to enumerate the lines, there's nothing left to fetch.

问题是你已经有效地读取了整个文件,所以当你去枚举这些行时,没有什么可以提取的了。

You should read the lines all at once, and evaluate that instead.

您应该一次阅读所有行,并对其进行评估。

f = open(MyFile, 'r')
lines = list(f)

# operate on lines instead of f!
# ...

#1


2  

Try doing both tasks together in a single pass over the file:

尝试在文件中一次完成两个任务:

with open(MyFile,'r') as f:
    searching = True
    for num, line in enumerate(f): 
        if searching and 'Results' in line:
            ResultLine=num
            searching = False
    lastline = num

#2


3  

If you want to work with the same file you need to rewind the file pointer. Just do f.seek(0) before your second enumeration

如果要使用同一文件,则需要回退文件指针。在第二次枚举之前,请执行f.seek(0)

However, getting into what your code is actually doing, it can be optimized to do all in the same loop

但是,要了解代码实际执行的操作,可以优化它以在同一个循环中执行所有操作

with open(MyFile,'r') as f:
    lastline = 0
    ResultLine = None

    for num, line in enumerate(f): 
        if not ResultLine and 'Results' in line:
            ResultLine=num

    lastline = num # + 1 if you want a count; this is what you actually get 
                   # in your sample, the count, not the last line index

#3


2  

with open(MyFile,'r') as f:
    lastline = sum(1 for line in f)

    ## The pointer f has reached the end of the file here
    ## Need to reset pointer back to beginning
    f.seek(0)

    for num, line in enumerate(f): 
        if 'Results' in line:
            ResultLine=num   
            break

#4


1  

with creates a contextmanager

与创建上下文管理器

contextmanagers will automatically clean up after them selves when you exit their scope ... (ie close the filehandle)

当你退出范围时,contextmanagers会自动清理它们...(即关闭文件句柄)

this answer only addresses why your filehandle is closed when you exit the with statement

此答案仅解决了退出with语句时关闭文件句柄的原因

see http://preshing.com/20110920/the-python-with-statement-by-example/ for some more info about the with statement and contextmanagers (first link that came up on googling for "file contextmanager")

有关with语句和contextmanagers的更多信息,请参阅http://preshing.com/20110920/the-python-with-statement-by-example/(google搜索“file contextmanager”时出现的第一个链接)

#5


-1  

The problem is that you've effectively read the entire file once already, so when you go to enumerate the lines, there's nothing left to fetch.

问题是你已经有效地读取了整个文件,所以当你去枚举这些行时,没有什么可以提取的了。

You should read the lines all at once, and evaluate that instead.

您应该一次阅读所有行,并对其进行评估。

f = open(MyFile, 'r')
lines = list(f)

# operate on lines instead of f!
# ...