Search code examples
pythonfilevalueerror

Failure to Re-open File after Closing


I have been working with some code that is meant to print a poem. The goal of the code is to make borders that will fit the poem's size. But that does not pertain to my issue. I have been trying to get the code to reprint a file, line for line, but ValueError: I/O operation on closed file. is all that is returned.

I've attempted to get around this by reopening the file after it's closed, and reopening it after the def poemprint(poem): function has completed. But both methods have failed. I don't know where to go from here.

import os
os.system("clear")

quitw=["no","n","ney","ne","nope","nuh-uh","nuh","noh","neigh","nye","negative","please no","no               please","quit","stop","q","s"]
harlem=open("harlem.txt","r")
hhop=open("hhop.txt","r")
poems={"1":harlem,"2":hhop}
poemname={"1":"harlem.txt","2":"hhop.txt"}

#10 lines of def quit() code

def poemprint(poem):
    print("╭"+"-"*60+"╮")
    print("|  Poem Printer [v0.5]"+" "*39+"|")
    print("⊢"+"-"*60+"⊣")
    print("|"+" "*60+"|")
    for a in poem: #line where error occurs
        b=57-len(a)
        print("|    "+a[0:len(a)-1]+(" "*b)+"|")
    print("|"+" "*60+"|")
    print("╰"+"-"*60+"╯")
    poem.close()
    if f=="harlem.txt": #doesn't work
        harlem=open("harlem.txt","r")
    elif f=="hhop.txt":
        hhop=open("hhop.txt","r")

c=(input("Enter a Poem: "))
if c not in quitw:
    while c not in quitw:
        while c.lower() in poems:
            os.system("clear")
            f=poemname[c]
            poemprint(poems[c])
            c=(input("Enter a Poem: "))
            if c in quitw:
                quit()
            else:
                continue
        os.system("clear")
        print("Invalid input.")
        c=(input("Enter a Poem: "))
else:
    quit()

Note: quit() is a defined function to stop the code entirely.

This is what I should be seeing after asking for the Harlem poem for the second time:

    ╭------------------------------------------------------------╮
    |  Poem Printer [v0.5]                                       |
    ⊢------------------------------------------------------------⊣
    |                                                            |
    |    Harlem by Langston Hughes                               |
    |                                                            |
    |      What happens to a dream deferred?                     |
    |                                                            |
    |        Does it dry up                                      |
    |        like a raisin in the sun?                           |
    |        Or fester like a sore—                              |
    |        And then run?                                       |
    |        Does it stink like rotten meat?                     |
    |        Or crust and sugar over—                            |
    |        like a syrupy sweet?                                |
    |                                                            |
    |        Maybe it just sags                                  |
    |        like a heavy load.                                  |
    |                                                            |
    |        Or does it explode?                                 |
    |                                                            |
    ╰------------------------------------------------------------╯

Instead, I'm getting:

    ╭------------------------------------------------------------╮
    |  Poem Printer [v0.5]                                       |
    ⊢------------------------------------------------------------⊣
    |                                                            |
    Traceback (most recent call last):
      File "main.py",line 44, in <module>
        poemsprint(poems[c])
      File "main.py",line 27, in poemprint
        for a in poem:
    ValueError: I/O operation of closed file.

Solution

  • Your steps are:

    1. You open a file in harlem variable
    2. You call poemprint function with harlem argument. This harlem is referenced as poem inside of the function.
    3. You close the file that poem references to (it is harlem outside of the function)
    4. You create a new variable harlem that exists only inside of the function
    5. After the function is done, you have harlem as a closed file

    This happens because harlem in the poemprint and the one outside are different objects.

    Short example:

    def a():
        var = 2
    
    var = 1
    a()
    
    print(var) #prints 1
    

    You can read more about this in mgilson's answer on a question that covers similar problem and in the Python documentation.

    How to fix:

    Instead of opening the files, keep their names.

    poems={"1":"harlem.txt","2":"hhop.txt"}
    

    Then modify the function to get the filename as the argument and to open the file inside of the function.

    def poemprint(poem):
        print("╭"+"-"*60+"╮")
        print("|  Poem Printer [v0.5]"+" "*39+"|")
        print("⊢"+"-"*60+"⊣")
        print("|"+" "*60+"|")
    
        poem = open(poem, "r") #This
        for a in poem:
            b=57-len(a)
            print("|    "+a[0:len(a)-1]+(" "*b)+"|")
        print("|"+" "*60+"|")
        print("╰"+"-"*60+"╯")
        poem.close()
        #End of the function
    

    Now it should work.

    Enter a Poem: 1
    ╭------------------------------------------------------------╮
    |  Poem Printer [v0.5]                                       |
    ⊢------------------------------------------------------------⊣
    |                                                            |
    |    Roses are red                                           |
    |    Violets are blue                                        |
    |                                                            |
    ╰------------------------------------------------------------╯
    Enter a Poem: 1
    ╭------------------------------------------------------------╮
    |  Poem Printer [v0.5]                                       |
    ⊢------------------------------------------------------------⊣
    |                                                            |
    |    Roses are red                                           |
    |    Violets are blue                                        |
    |                                                            |
    ╰------------------------------------------------------------╯
    Enter a Poem: 
    
    

    Here's the full code:

    import os
    os.system("clear")
    
    quitw=["no","n","ney","ne","nope","nuh-uh","nuh","noh","neigh","nye","negative","please no","no               please","quit","stop","q","s"]
    poems={"1":"harlem.txt","2":"hhop.txt"}
    
    #10 lines of def quit() code
    
    def poemprint(poem):
        print("╭"+"-"*60+"╮")
        print("|  Poem Printer [v0.5]"+" "*39+"|")
        print("⊢"+"-"*60+"⊣")
        print("|"+" "*60+"|")
    
        poem = open(poem, "r") #This
        for a in poem:
            b=57-len(a)
            print("|    "+a[0:len(a)-1]+(" "*b)+"|")
        print("|"+" "*60+"|")
        print("╰"+"-"*60+"╯")
        poem.close()
    
    c=(input("Enter a Poem: "))
    if c not in quitw:
        while c not in quitw:
            while c.lower() in poems:
                os.system("clear")
                f=poems[c]
                poemprint(poems[c])
                c=(input("Enter a Poem: "))
                if c in quitw:
                    quit()
                else:
                    continue
            os.system("clear")
            print("Invalid input.")
            c=(input("Enter a Poem: "))
    else:
        quit()