Home > Blockchain >  By using context manager, my code writes the text in descending order (second line first instead of
By using context manager, my code writes the text in descending order (second line first instead of

Time:04-14

I am trying to write html using class in Python. Some guidance have been given by my lecturer. When I try to use with function to write text into the HTML file, the lines below the first initiation are written into the file first. Can I know how to solve it?

Code:

class DOM:
    class HtmlTable:
        def __init__(self, indent, tag_name):
            self.indent = indent
            self.tag_name = tag_name
            
        def __enter__(self):
            self.file = open('test.html', 'a')
            self.file.write(f'{self.indent*"  "}<{self.tag_name} >\n')
            return self.file

        def __exit__(self, exception_type, exception_value, traceback):
            self.file.write(f'{self.indent*"  "}</{self.tag_name}>\n')
            self.file.close()
    
    def __init__(self):
        self.indent = -2

    def tag(self, tag_name):
        self.indent  = 2
        return self.HtmlTable(self.indent, tag_name)

Test:

if __name__ == '__main__':
    doc = DOM()
    with doc.tag('html'):
        with doc.tag('head'):
            #remaining code

Output:

    <head >
    </head>
<html >
</html>

Desired Output:

<html >
    <head >
    </head>
</html>

CodePudding user response:

You may want to .flush() your file - only on "flush" the actual file content is written to disc - until then the file object caches what needs to be done in its internal buffer:

class DOM: 
    class HtmlTable:
        def __init__(self, indent, tag_name):
            self.indent = indent
            self.tag_name = tag_name
            
        def __enter__(self):
            self.file = open('test.html', 'a ')
            self.file.write(f'{self.indent*"  "}<{self.tag_name} >\n') 
            self.file.flush()  ########## here ##########
            return self.file


        def __exit__(self, exception_type, exception_value, traceback):
            self.file.write(f'{self.indent*"  "}</{self.tag_name}>\n')
            self.file.close()

    # fixed indentation        
    def __init__(self):
        self.indent = -2

    # fixed indentation        
    def tag(self, tag_name):
        self.indent  = 2        
        return self.HtmlTable(self.indent, tag_name)


def main():
    with open("test.html","w") as f:
        f.write("\n")

    doc = DOM()
    with doc.tag('html'):
        pass
        with doc.tag('head'):
            pass

    print(open("test.html").read())

if __name__ == '__main__':
    main()

==>

<html >
    <head >
    </head>
</html>

Currently the file itself flushes its buffer to disc when needed - it "is needed" when you hit self.file.close() in your __exit__(). The first __exit__ is done for the tag "head".

Until the file is "flushed" the "things to be written" are kept in the file objects internal buffer - that is the reason for the output you are getting.

  • Related