5

My goal is to use multiple functions to search for strings in a log.

I am running into an issue where only the 1st function called after opening the file retrieves the entire contents of the file. All other functions do not retrieve any contents of the open file.

For testing I used a simple file with the following text:

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

This is the section of my code that is the problem.

def main():
    with open('myinputfile.txt', 'r') as myfile:
        get_aaa(myfile)
        get_bbb(myfile)
        get_fff(myfile)

Each get_xxx function simply searches for a string. get_aaa() searches for ^aaa, get_bbb() searches for ^bbb, and get_fff() searches for ^fff. If the string is found the function prints some text along with the matching line. If the string is not found a "NOT FOUND" message is printed.

When running the script I receive this output:

Start Date:  aaa this is line 1
ITEM BBB: NOT FOUND
ITEM FFF: NOT FOUND

When I modify the main() and reordering to call get_bbb() before get_aaa() I receive this output:

Start Time:  bbb this is line 2
ITEM AAA: NOT FOUND
ITEM FFF: NOT FOUND

Based on this testing I am sure only the 1st function called after opening the file is reading the entire contents of file.

For additional testing I found if I open the file prior to calling each function - I receive the expected output.

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(

Results in the expected output.

Start Date:  aaa this is line 1
Start Time:  bbb this is line 2
UserId :     fff this is line 6

Any hints on how I can open a file once and search the contents of the file using multiple functions?

1
  • 2
    This is a properly asked question. Very refreshing to see. Good work on creating a minimal example based on testing and deductions Commented Oct 6, 2019 at 4:06

3 Answers 3

3

How to pass open file as a variable to multiple functions?

You've done it correctly.

As to why this does not work:

def main():
    with open('myinputfile.txt', 'r') as myfile:
        get_aaa(myfile)
        get_bbb(myfile)
        get_fff(myfile)

but this does:

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)

The answer lies in the fact that files are read as streams of text. So after you've gone through the whole thing, you have you "rewind" back. This can be done with the seek method.

I haven't tested, but this code should work:

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

But I think you'll be much better off with a string variable, see the Lamanus answer. The difference here is, strings are stateless and immutable, and therefore much more predictable in their behavior than file objects.

Sign up to request clarification or add additional context in comments.

Comments

2

Read your file first, and apply the functions.

def get_aaa(lines):
    for line in lines.split('\n'):
        if line.startswith('aaa'): return line 

def get_bbb(lines):
    for line in lines.split('\n'):
        if line.startswith('bbb'): return line 

def get_ccc(lines):
    for line in lines.split('\n'):
        if line.startswith('ccc'): return line 

def main():
    with open('test.txt', 'r') as myfile:
        lines = myfile.read()
        print(get_aaa(lines))
        print(get_bbb(lines))
        print(get_ccc(lines))

main()

The result is

aaa this is line 1
bbb this is line 2
ccc this is line 3

Comments

0

1

def get_aaa(file):
    print("\n\naaa\n")
    print(file)

def get_bbb(file):
    print("\n\nbbb\n")
    print(file)

def get_fff(file):
    print("\n\nfff\n")
    print(file)




def main():
    with open('text.txt', 'r') as myfile:
        file = myfile.read()
        get_aaa(file)
        get_bbb(file)
        get_fff(file)

main()

2

def get_aaa(file):
    print("\n\naaa\n")
    print(file)

def get_bbb(file):
    print("\n\nbbb\n")
    print(file)

def get_fff(file):
    print("\n\nfff\n")
    print(file)

def main():
    with open('text.txt', 'r') as file:
        get_aaa(file.read())
        file.seek(0)
        get_bbb(file.read())
        file.seek(0)
        get_fff(file.read())

main()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.