printing dynamically string in one line in python

2019-02-11 04:40发布

问题:

I'm trying to print strings in one line.

I've found solutions but they don't works with windows correctly.

I have text file contains names and I want to print them like this

name=john then change john to next name and keep name=, I've made this code but didn't work correctly with windows:

op = open('names.txt','r')
print 'name=',
for i in op.readlines():
    print '\r'+i.strip('\n')

thank you for your time

回答1:

Using '\b' as suggested by senderle

import sys
import time

sys.stdout.write('name=')
last_lenght = 0
with open('names.txt') as names:
    for name in names:
        sys.stdout.write('\b' * last_lenght)    # go back
        sys.stdout.write(' ' * last_lenght)     # clear last name
        sys.stdout.write('\b' * last_lenght)    # reposition
        sys.stdout.write(name.strip())
        sys.stdout.flush()
        last_lenght = len(name.strip())
        time.sleep(0.5)


回答2:

Simply using \r won't work in this case, because that returns you to the beginning of the line, so you'll have to reprint the entire line. Also, in some systems (including Windows, I think) Python's print statement (function in 3+) interprets \r as a newline. I believe this code should be system-independent.

import sys, time

with open('names.txt', 'r') as names:
    prev_len = 0
    for name in names:
        sys.stdout.write('\r' + ' ' * prev_len)
        sys.stdout.flush()
        output_string = '\rname={}'.format(name.strip())
        prev_len = len(output_string)
        sys.stdout.write(output_string)
        sys.stdout.flush()
        time.sleep(0.3)
print

You could also use \b, which generally moves the cursor back by one space.

As you pointed out, it's necessary to overwrite the previously printed line with spaces, which means it's necessary to remember the length of the previous line. It makes sense to encapsulate that state in an object, I think. Here's a much cleaner solution than the above that uses that strategy:

import sys, time

class LineUpdater(object):
    def __init__(self, outfile=None):
        self.prev_len = 0
        self.outfile = sys.stdout if outfile is None else outfile

    def write(self, line):
        line = line.strip()
        output = '\r{:<{width}}'.format(line, width=self.prev_len)
        self.prev_len = len(line)
        self.outfile.write(output)
        self.outfile.flush()

with open('names.txt', 'r') as names:
    out = LineUpdater()
    for name in names:
        out.write('name={}'.format(name))
        time.sleep(0.3)
    print