Search code examples
pythonpython-3.xstring-formatting

Formatting function with similar signature to print function


I have some code that prints stuff to console using some of the print function's capabilities, e.g.

print('name'.ljust(44), 'age'.rjust(4), 'idea'.rjust(8), sep=',')
for name, age, idea in items:    
    print(name.ljust(44), str(age).rjust(4), idea.rjust(8), sep=',')

In other cases I will use the end parameter to write multiple strings to a single line, i.e.

print('hello ', end='')
print('world!')

My question is how could I most easily write this print formatted output to a stream, a file, or even better just collect into a single string object? If I revert to regular string formatting the syntax will be different and I'll need to re-write all my formatting.


Solution

  • StringIO allows you to use a string as if it were a file. Along with using print(..., file=...) you can then do:

    import io
    
    with io.StringIO() as fp:
        print("hi", "mom", sep=" ", file=fp)
        print('hello ', end='', file=fp)
        print('world!', file=fp)
    
        str = fp.getvalue()
    
    print(str)
    

    which gives

    hi mom
    hello world!
    

    as (I think) you want. You can also use fp.readlines() if you want a list of strings for each line.

    You can also use a tempfile which may use the filesystem (but may not), with almost identical syntax:

    import tempfile
    
    with tempfile.TemporaryFile(mode="w+") as fp:
        print("hi", "mom", sep=" ", file=fp)
        print('hello ', end='', file=fp)
        print('world!', file=fp)
    
        fp.seek(0)
        str = fp.read()
    
    print(str)
    

    You do need to specify the mode as the default gives a binary file which doesn't let you print, and explicitly rewind back to the beginning before reading. (FWIW, an earlier version of my answer had flush=True for each print but I don't think that's needed.)