简体   繁体   中英

How to print between last and second-to-last lines in console?

Using Python 3.4, is there a platform-agnostic method of printing between the last and second-to-last lines? What I'm trying to accomplish is basically a progress bar always on the last line. The 2nd line and up are just debug logs. For example:

[DEBUG] Some info...
[DEBUG] More info...
Download Progress: [####      ] 40% (3 of 20)

I run some downloads in a loop. Each iteration of the loop I run this to print the progress bar:

def _print_progress_bar(self):
    amt_done = self._count / self._max
    print('\rDownload Progress: [{:20s}] {:.1f}% ({})'.format(
        '#' * int(amt_done * 20),
        amt_done * 100,
        self._padded_counter(' of ')), end='')

Between calls to this method to render the progress bar, I want to insert diagnostic messages above it (I do not want print statements after this to overwrite the progress bar, basically).

How can I do this?

You can get this effect by using the carriage return, '\\r' . On Windows, this is the character that gets combined with a linefeed ( '\\n' ) to create a new line. On Unix systems, a bare linefeed automatically returns the carriage, but '\\r' is still a valid character. For example, print('hi\\rhello') will print 'hi' , go back to the beginning of the line, and print 'hello' , so only 'hello' ends up actually displayed. You can use end='' to suppress print() 's new line. The following function demonstrates what to do - I recommend running it to see what happens for yourself, as the output is, of course, dynamic.

>>> import time, sys
>>> def doit():
...     print('part 1')
...     print(0, end='')
...     sys.stdout.flush()
...     time.sleep(1)
...     print('\rpart 2')
...     print(1)
...
>>> doit()
part 1
part 2
1

The best way I could find was to use terminal escape codes like this:

for i in range(10):
    time.sleep(0.1)
    print('%s\n%s\r\033[F' % (i,i), end="")

This will print a number in one line, then in another line, then move to beginning of the line and one line up to print again. This way you can freely edit lines above you.

This solution however has the potential of not working on Windows.

You need to modify your DEBUG function to erase the line before printing. It is the only platform agnostic way I know.

Platform specific way on Windows is to use WinAPI to scroll the upper part of the Window and write exactly to the line above the last. Maybe a library like https://pypi.python.org/pypi/asciimatics/1.5.0.post1 can help you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM