Bagaimana cara menulis output di tempat yang sama di konsol?


158

Saya baru mengenal python dan sedang menulis beberapa skrip untuk mengotomatisasi pengunduhan file dari server FTP, dll. Saya ingin menunjukkan progres pengunduhan, tetapi saya ingin tetap pada posisi yang sama, seperti:

keluaran:

Mengunduh File FooFile.txt [47%]

Saya mencoba menghindari sesuatu seperti ini:

     Downloading File FooFile.txt [47%]
     Downloading File FooFile.txt [48%]
     Downloading File FooFile.txt [49%]

Bagaimana saya harus melakukan ini?


Gandakan : Bagaimana saya bisa mencetak pada baris saat ini dalam aplikasi baris perintah?


1
Anda mungkin tertarik pada modul yang mudah digunakan ini, ini adalah bilah kemajuan teks. pypi.python.org/pypi/progressbar/2.2
wim

Jawaban:


254

Anda juga dapat menggunakan carriage return:

sys.stdout.write("Download progress: %d%%   \r" % (progress) )
sys.stdout.flush()

13
Solusi yang sangat umum dan sederhana. Catatan: jika saluran Anda lebih panjang dari lebar terminal Anda, ini menjadi jelek.
ephemient

5
Saya juga harus menambahkan panggilan ke sys.stdout.flush () sehingga kursor tidak terpental sekitar
scottm

19
Apakah mungkin melakukan ini dengan beberapa baris? Katakanlah saya memiliki tiga unduhan berbeda, dan saya ingin menunjukkan kemajuan masing-masing pada jalurnya sendiri.
EarlCrapstone

11
Saya suka meletakkan \rdi awal baris, dan menambahkan \x1b[Kuntuk menghapus teks sebelumnya.
augurar

11
Sepertinya solusi paling sederhana untuk python 3 (seperti yang disebutkan dalam jawaban di bawah) adalah: print("sample text", end='\r", flush=True)
Cyrus

35

Python 2

Saya suka yang berikut ini:

print 'Downloading File FooFile.txt [%d%%]\r'%i,

Demo:

import time

for i in range(100):
    time.sleep(0.1)
    print 'Downloading File FooFile.txt [%d%%]\r'%i,

Python 3

print('Downloading File FooFile.txt [%d%%]\r'%i, end="")

Demo:

import time

for i in range(100):
    time.sleep(0.1)
    print('Downloading File FooFile.txt [%d%%]\r'%i, end="")

PyCharm Debugger Console dengan Python 3

# On PyCharm Debugger console, \r needs to come before the text.
# Otherwise, the text may not appear at all, or appear inconsistently.
# tested on PyCharm 2019.3, Python 3.6

import time

print('Start.')
for i in range(100):
    time.sleep(0.02)
    print('\rDownloading File FooFile.txt [%d%%]'%i, end="")
print('\nDone.')

9
gunakan ini untuk python 3+: print ('Mengunduh File FooFile.txt [% d %%] \ r'% i, end = "")
hkoosha

Di konsol PyCharm Debugger, harus ada sebelum teks. Jika tidak, teks mungkin tidak muncul sama sekali, atau muncul tidak konsisten. Saya menambahkan versi yang berfungsi untuk saya sebagai edit, karena saya tidak bisa menulis kode multi-baris dalam jawaban ini. Saya meletakkannya di intisari saya sehingga orang-orang dapat melihatnya saat suntingan sedang menunggu persetujuan: gist.github.com/yulkang/40168c7729a7a7b96d0116d8b1bc26df
Yul Kang

"\ r" di akhir string berfungsi untuk saya di konsol debugger di PyCharm 2020.1 (PyCharm 2020.1.2 (Edisi Komunitas); Build # PC-201.7846.77, dibangun pada 31 Mei 2020).
bertempurlah


15

Cetak karakter backspace \bbeberapa kali, dan kemudian timpa nomor lama dengan nomor baru.


menarik, saya tidak berpikir untuk melakukannya dengan cara itu.
Chris Ballance

Saya suka ini karena tidak menghapus perintah sebelumnya (jika Anda memiliki beberapa tahapan yang ingin Anda tinggalkan di layar)
Nathan Donnellan

3
Menggunakan carriage return (mis. print 'Downloading.... \r') Juga tidak menghapus data sebelumnya, tetapi mencegah harus mengetahui seberapa jauh cadangannya.
cod3monk3y

8
#kinda like the one above but better :P

from __future__ import print_function
from time import sleep

for i in range(101):
  str1="Downloading File FooFile.txt [{}%]".format(i)
  back="\b"*len(str1)
  print(str1, end="")
  sleep(0.1)
  print(back, end="")

Mengapa ini lebih baik daripada yang di atas (saya adalah Python n00b, jadi tolong permisi ketidaktahuan saya :-))?
BalinKingOfMoria Reinstate CMs

7

Untuk Python 3xx:

import time
for i in range(10):
    time.sleep(0.2) 
    print ("\r Loading... {}".format(i)+str(i), end="")

4

Solusi rapi yang telah bekerja untuk saya adalah:

from __future__ import print_function
import sys
for i in range(10**6):
    perc = float(i) / 10**6 * 100
    print(">>> Download is {}% complete      ".format(perc), end='\r')
    sys.stdout.flush()
print("")

The sys.stdout.flushpenting jika tidak akan benar-benar kikuk dan print("")pada loop keluar juga penting.

UPDATE : Seperti yang disebutkan dalam komentar, printjuga memiliki flushargumen. Jadi yang berikut ini juga akan berfungsi:

from __future__ import print_function
for i in range(10**6):
    perc = float(i) / 10**6 * 100
    print(">>> Download is {}% complete      ".format(perc), end='\r', flush=True)
print("")

1
Dalam Python modern, Anda bisa menyediakan argumen flush=Trueuntuk print, jadi tidak perlu untuk sys.stdout.flush()panggilan ekstra .
PM 2Ring

0
x="A Sting {}"
   for i in range(0,1000000):
y=list(x.format(i))
print(x.format(i),end="")

for j in range(0,len(y)):
    print("\b",end="")
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.