banyak cetakan pada baris yang sama dengan Python

229

Saya ingin menjalankan skrip, yang pada dasarnya menunjukkan keluaran seperti ini:

Installing XXX...               [DONE]

Saat ini, saya mencetak Installing XXX...dulu dan kemudian saya mencetak [DONE].

Namun, sekarang saya ingin mencetak Installing xxx...dan [DONE]pada baris yang sama.

Ada ide?

user697108
sumber
1
Jawaban untuk pertanyaan ini tidak menyebutkan bahwa kadang-kadang Anda ingin menghapus garis, lihat: stackoverflow.com/questions/45263205
ideasman42

Jawaban:

284

Anda dapat menggunakan printpernyataan untuk melakukan ini tanpa mengimpor sys.

def install_xxx():
   print "Installing XXX...      ",

install_xxx()
print "[DONE]"

Koma di ujung printbaris mencegah printdari mengeluarkan baris baru (Anda harus mencatat bahwa akan ada ruang tambahan di akhir output).

Solusi Python 3
Karena hal di atas tidak berfungsi di Python 3, Anda dapat melakukan ini sebagai gantinya (sekali lagi, tanpa mengimpor sys):

def install_xxx():
    print("Installing XXX...      ", end="", flush=True)

install_xxx()
print("[DONE]")

Fungsi cetak menerima endparameter yang standarnya "\n". Mengaturnya ke string kosong akan mencegahnya mengeluarkan baris baru di akhir baris.

beberapa antarmuka
sumber
1
Ini bekerja dengan sempurna. Hanya melihat solusi stdout sejauh ini. Senang mengetahui hal itu.
Prometheus
5
Ini tidak berfungsi jika Anda memiliki keduanya hasil cetak dan tindakan yang menghabiskan waktu (semua dalam level fungsi / indentasi yang sama). Sebelum aksi dimulai, tidak ada output sama sekali dan setelah selesai output muncul secara keseluruhan
Paddre
2
Itu mungkin lebih merupakan fungsi dari buffering output yang dibentuk sebelumnya oleh OS untuk proses secara keseluruhan, yang bukan merupakan masalah khusus-python. Lihat stackoverflow.com/questions/107705 untuk solusi khusus python.
beberapa
13
Tanpa baris baru, Anda mungkin ingin menyiram buffer secara eksplisit. Gunakan print("...", end="", flush=True)di Python 3, di Python 2 tambahkan sys.stdout.flush()panggilan.
Martijn Pieters
7
dalam python 3.x Anda ingin menambahkan "\ r" untuk mengakhiri untuk mengganti garis cetak VS menambahkan ke akhirprint("Progress: {}%".format(var), end="\r", flush=True)
John
103

Anda cukup menggunakan ini:

print 'something',
...
print ' else',

dan hasilnya akan

something else

tidak perlu berlebihan oleh import sys. Perhatikan simbol koma di bagian akhir.

Python 3+ print("some string", end=""); untuk menghapus insert baris baru di akhir. Baca lebih lanjut olehhelp(print);

boldnik
sumber
3
Perhatikan ada dua ruang dengan menggunakan metode ini
ethanjyx
1
Ini adalah jawaban yang paling sederhana dan paling efisien.
gixxer
Ini tidak berfungsi ketika argumen pencetakan ada dalam tanda kurung. Ini berfungsi: <print "hello",; print ("hello")> tetapi ini tidak berhasil <print ("hello",); print ("hello")>
Mayank Jaiswal
@MayankJaiswal Ini berfungsi dengan parens. print ('hello'),
drglove
1
printfungsi memiliki sintaks yang sedikit berbeda di python 2 VS 3.
boldnik
52

Anda harus menggunakan karakter backspace ' \ r ' atau (' \ x08 ') untuk kembali ke posisi sebelumnya dalam output konsol

Python 2+:

import time
import sys

def backspace(n):
    sys.stdout.write((b'\x08' * n).decode()) # use \x08 char to go back   

for i in range(101):                        # for 0 to 100
    s = str(i) + '%'                        # string for output
    sys.stdout.write(s)                     # just print
    sys.stdout.flush()                      # needed for flush when using \x08
    backspace(len(s))                       # back n chars    
    time.sleep(0.2)                         # sleep for 200ms

Python 3:

import time   

def backline():        
    print('\r', end='')                     # use '\r' to go back


for i in range(101):                        # for 0 to 100
    s = str(i) + '%'                        # string for output
    print(s, end='')                        # just print and flush
    backline()                              # back to the beginning of line    
    time.sleep(0.2)                         # sleep for 200ms

Kode ini akan dihitung dari 0% hingga 100% pada satu baris. Nilai akhir adalah:

> python test.py
100%

Info tambahan tentang flush dalam kasus ini di sini: Mengapa pernyataan cetak python yang berisi argumen 'end =' berperilaku berbeda di while-loop?

Vadim Zin4uk
sumber
1
Untuk memperjelas, sepertinya kode yang dikomentari dalam contoh ini adalah untuk Python 2, dan baris yang tidak dikomentari adalah untuk Python 3.
Turtles Are Cute
1
bouth lines akan bekerja dengan baik di Python 3. Jika Anda menggunakan '\ x08' sebagai backspace Anda perlu menyiram aliran keluaran - cetak ((b '\ x08' * n) .decode (), end = '', flush = Benar)
Vadim Zin4uk
1
Pengembalian carriage '\ r' kembali ke awal baris, jadi '* n' tidak perlu
bjnortier
43

Gunakan sys.stdout.write('Installing XXX... ')dan sys.stdout.write('Done'). Dengan cara ini, Anda harus menambahkan baris baru dengan tangan "\n"jika Anda ingin membuat ulang fungsi cetak. Saya pikir mungkin tidak perlu menggunakan kutukan hanya untuk ini.

ferostar
sumber
4
Saya pribadi lebih suka solusi ini daripada yang lebih tinggi karena ia bekerja dengan cara yang sama persis pada python2.x dan python3.x tanpa perlu bergantung pada __future__impor atau hal-hal seperti itu.
mgilson
17

Tidak ada jawaban yang bekerja untuk saya karena mereka semua berhenti sampai baris baru ditemukan. Saya menulis pembantu sederhana:

def print_no_newline(string):
    import sys
    sys.stdout.write(string)
    sys.stdout.flush()

Untuk mengujinya:

import time
print_no_newline('hello ')
# Simulate a long task
time.sleep(2)
print('world')

"Halo" pertama-tama akan mencetak dan menyiram layar sebelum tidur. Setelah itu Anda dapat menggunakan cetakan standar.

hyprnick
sumber
1
Terima kasih! Persis apa yang saya butuhkan alias flush ()
MrNice
11

Paling sederhana:

Python 3

    print('\r' + 'something to be override', end='')

Ini berarti akan mengembalikan kursor ke awal, daripada akan mencetak sesuatu dan akan berakhir di baris yang sama. Jika dalam satu lingkaran itu akan mulai mencetak di tempat yang sama itu dimulai.

Sunfloro
sumber
3
Keren! Bekerja di Windows juga.
Shital Shah
2
Terima kasih ini bekerja dengan baik untuk saya! Saya pikir itu print(’something to be override’, end=‘\r’)lebih sederhana.
Tropilio
9

Contoh sederhana ini akan mencetak 1-10 pada baris yang sama.

for i in range(1,11):
    print (i, end=" ")
Umali Leonard
sumber
9

Cetak memiliki endargumen opsional , itulah yang dicetak pada akhirnya. Defaultnya adalah baris baru, tetapi Anda bisa mengubahnya menjadi string kosong. misalnyaprint("hello world!", end="")

TulkinRB
sumber
2
Ini dalam python 3. Dalam python 2 Anda bisa dengan mudah print 'something',. Koma di akhir mencegah penambahan baris baru.
arjoonn
4

Jika Anda ingin menimpa baris sebelumnya (daripada terus-menerus menambahkannya), Anda dapat menggabungkan \rdengan print(),di akhir pernyataan cetak. Sebagai contoh,

from time import sleep

for i in xrange(0, 10):
    print("\r{0}".format(i)),
    sleep(.5)

print("...DONE!")

akan menghitung 0 hingga 9, menggantikan nomor lama di konsol. Itu"...DONE!" akan mencetak pada baris yang sama seperti counter terakhir, 9.

Dalam kasus Anda untuk OP, ini akan memungkinkan konsol untuk menampilkan persen selesai menginstal sebagai "progress bar", di mana Anda dapat menentukan posisi karakter awal dan akhir, dan memperbarui penanda di antaranya.

print("Installing |XXXXXX              | 30%"),
Brian Bunker
sumber
4

Di sini versi 2,7 yang kompatibel berasal dari versi 3.0 oleh @ Vadim-Zin4uk:

Python 2

import time

for i in range(101):                        # for 0 to 100
    s = str(i) + '%'                        # string for output
    print '{0}\r'.format(s),                # just print and flush

    time.sleep(0.2)

Untuk itu, solusi 3.0 yang disediakan terlihat sedikit kembung. Sebagai contoh, metode backspace tidak menggunakan argumen integer dan mungkin bisa dihilangkan sama sekali.

Python 3

import time

for i in range(101):                        # for 0 to 100
    s = str(i) + '%'                        # string for output
    print('{0}\r'.format(s), end='')        # just print and flush

    time.sleep(0.2)                         # sleep for 200ms

Keduanya telah diuji dan bekerja.

Dannid
sumber
2

Ini adalah utas yang sangat lama, tetapi inilah jawaban yang sangat teliti dan kode sampel.

\radalah representasi string dari Carriage Return dari set karakter ASCII. Ini sama dengan oktal 015[ chr(0o15)] atau heksidimal 0d[ chr(0x0d)] atau desimal 13[ chr(13)]. Lihat man asciiuntuk membaca yang membosankan. Ini ( \r) adalah representasi yang cukup portabel dan cukup mudah bagi orang untuk membaca. Ini sangat sederhana artinya memindahkan carriage pada mesin tik sepanjang perjalanan kembali ke awal tanpa memajukan kertas. Itu CRbagian CRLFyang berarti Pengembalian Carriage dan Line Line .

print()adalah fungsi dalam Python 3. Dalam Python 2 (versi apa pun yang Anda tertarik untuk menggunakan), printdapat dipaksa menjadi fungsi dengan mengimpor definisi dari __future__modul. Manfaat dari printfungsi ini adalah Anda dapat menentukan apa yang akan dicetak pada akhirnya, mengesampingkan perilaku default \nuntuk mencetak baris baru di akhir setiap print()panggilan.

sys.stdout.flushmemberitahu Python untuk menyiram output dari output standar , yang merupakan tempat Anda mengirim output print()kecuali Anda menentukan sebaliknya. Anda juga bisa mendapatkan perilaku yang sama dengan berjalan dengan python -uatau mengatur variabel lingkungan PYTHONUNBUFFERED=1, sehingga melewatkan import sysdan sys.stdout.flush()panggilan. Jumlah yang Anda peroleh dengan melakukan hal itu hampir persis nol dan tidak terlalu mudah untuk di-debug jika Anda lupa bahwa Anda harus melakukan langkah itu sebelum aplikasi Anda berperilaku baik.

Dan sampel. Perhatikan bahwa ini berjalan dengan sempurna di Python 2 atau 3.

from __future__ import print_function

import sys
import time

ANS = 42
FACTORS = {n for n in range(1, ANS + 1) if ANS % n == 0}

for i in range(1, ANS + 1):
    if i in FACTORS:
        print('\r{0:d}'.format(i), end='')
        sys.stdout.flush()
        time.sleep(ANS / 100.0)
else:
    print()
Chris Cosby
sumber
Saya pikir jawaban Anda lebih cocok untuk: stackoverflow.com/questions/45263205/…
Marc Cayuela Rafols
2

print () memiliki parameter bawaan "end" yang secara default diatur ke "\ n" Memanggil print ("This is America") sebenarnya memanggil print ("This is America", end = "\ n"). Cara mudah untuk dilakukan adalah dengan memanggil print ("Ini Amerika", end = "")

Miles Mbo
sumber
1

Untuk berjaga-jaga jika Anda telah menyimpan nilai-nilai dalam array, Anda dapat memanggilnya dalam format berikut:

for i in range(0,n):
       print arr[i],
k20392
sumber
1

Python menambahkan baris baru sebagai akhir untuk mencetak. Gunakan end = '' untuk python3 untuk metode cetak untuk menambahkan spasi alih-alih baris baru. untuk python2 gunakan koma di akhir pernyataan cetak.

print("Foo",end=' ')
print('Bar')
MrKulli
sumber
0

Ditemukan posting Quora ini , dengan contoh ini yang bekerja untuk saya (python 3), yang lebih dekat dengan apa yang saya butuhkan untuk itu (yaitu menghapus seluruh baris sebelumnya).

Contoh yang mereka berikan:

def clock():
   while True:
       print(datetime.now().strftime("%H:%M:%S"), end="\r")

Untuk mencetak pada baris yang sama, seperti yang disarankan orang lain, gunakan saja end=""

Mircea
sumber
-2

Saya menemukan solusi ini, dan sedang bekerja pada Python 2.7

# Working on Python 2.7 Linux

import time
import sys


def backspace(n):
    print('\r', end='')                     # use '\r' to go back


for i in range(101):                        # for 0 to 100
    s = str(i) + '%'                        # string for output
    sys.stdout.write(string)
    backspace(len(s))                       # back for n chars
    sys.stdout.flush()
    time.sleep(0.2)                         # sleep for 200ms
Luis Silva
sumber
1
Itu printsintaks yang salah untuk Python 2.7 dan kode tidak bekerja bahkan dengan sintaks yang benar.
Cory Madden