如何将打开的文件作为变量传递给多个函数?

Dav*_*idW 5 python-3.x

我的目标是使用多个函数来搜索日志中的字符串。

我遇到一个问题,只有打开文件后调用的第一个函数才能检索文件的全部内容。所有其他函数不会检索打开文件的任何内容。

为了进行测试,我使用了一个包含以下文本的简单文件:

aaa this is line 1
bbb this is line 2
ccc this is line 3
ddd this is line 4
eee this is line 5
fff this is line 6
ggg this is line 7
Run Code Online (Sandbox Code Playgroud)

这是我的代码中有问题的部分。

def main():
    with open('myinputfile.txt', 'r') as myfile:
        get_aaa(myfile)
        get_bbb(myfile)
        get_fff(myfile)
Run Code Online (Sandbox Code Playgroud)

每个 get_xxx 函数只是搜索一个字符串。get_aaa() 搜索 ^aaa,get_bbb() 搜索 ^bbb,get_fff() 搜索 ^fff。如果找到该字符串,该函数将打印一些文本以及匹配的行。如果未找到该字符串,则会打印“NOT FOUND”消息。

运行脚本时,我收到以下输出:

Start Date:  aaa this is line 1
ITEM BBB: NOT FOUND
ITEM FFF: NOT FOUND
Run Code Online (Sandbox Code Playgroud)

当我修改 main() 并重新排序以在 get_aaa() 之前调用 get_bbb() 时,我收到以下输出:

Start Time:  bbb this is line 2
ITEM AAA: NOT FOUND
ITEM FFF: NOT FOUND
Run Code Online (Sandbox Code Playgroud)

根据此测试,我确信只有打开文件后调用的第一个函数正在读取文件的全部内容。

对于额外的测试,我发现如果我在调用每个函数之前打开文件 - 我会收到预期的输出。

def main():
    with open('myinputfile.txt', 'r') as myfile:
        get_aaa(myfile)
    with open('myinputfile.txt', 'r') as myfile:
        get_bbb(myfile)
    with open('myinputfile.txt', 'r') as myfile:
        get_fff(myfile)
        myfile.close(
Run Code Online (Sandbox Code Playgroud)

产生预期的输出。

Start Date:  aaa this is line 1
Start Time:  bbb this is line 2
UserId :     fff this is line 6
Run Code Online (Sandbox Code Playgroud)

有关如何打开一次文件并使用多个函数搜索文件内容的任何提示?

Pav*_*eev 3

如何将打开的文件作为变量传递给多个函数?

你做对了。

至于为什么这不起作用:

def main():
    with open('myinputfile.txt', 'r') as myfile:
        get_aaa(myfile)
        get_bbb(myfile)
        get_fff(myfile)
Run Code Online (Sandbox Code Playgroud)

但这确实:

def main():
    with open('myinputfile.txt', 'r') as myfile:
        get_aaa(myfile)
    with open('myinputfile.txt', 'r') as myfile:
        get_bbb(myfile)
    with open('myinputfile.txt', 'r') as myfile:
        get_fff(myfile)
Run Code Online (Sandbox Code Playgroud)

答案在于文件是作为文本流读取的。因此,在您完成整个事情之后,您可以“倒带”回来。这可以通过seek方法来完成。

我还没有测试过,但这段代码应该可以工作:

def main():
    with open('myinputfile.txt', 'r') as myfile:
        get_aaa(myfile)
        myfile.seek(0)
        get_bbb(myfile)
        myfile.seek(0)
        get_fff(myfile)
Run Code Online (Sandbox Code Playgroud)

但我认为使用字符串变量会更好,请参阅Lamanus 答案。这里的区别在于,字符串是无状态且不可变的,因此其行为比文件对象更可预测。