พิมพ์หลายงานบนบรรทัดเดียวกันใน Python


229

ฉันต้องการเรียกใช้สคริปต์ซึ่งโดยทั่วไปจะแสดงผลลัพธ์เช่นนี้

Installing XXX...               [DONE]

ขณะนี้ฉันพิมพ์ครั้งแรกแล้วฉันจะพิมพ์Installing XXX...[DONE]

อย่างไรก็ตามตอนนี้ฉันต้องการพิมพ์Installing xxx...และ[DONE]ในบรรทัดเดียวกัน

ความคิดใด ๆ



1
คำตอบสำหรับคำถามนี้ไม่ได้กล่าวถึงว่าบางครั้งคุณต้องการล้างข้อมูลบรรทัดโปรดดู: stackoverflow.com/questions/45263205
คิด man42 42

คำตอบ:


284

คุณสามารถใช้คำสั่งให้ทำเช่นนี้ได้โดยไม่ต้องนำเข้าprintsys

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

install_xxx()
print "[DONE]"

เครื่องหมายจุลภาคที่ท้ายprintบรรทัดป้องกันไม่ให้printออกบรรทัดใหม่ (คุณควรทราบว่าจะมีช่องว่างเพิ่มเติมในตอนท้ายของเอาต์พุต)

โซลูชัน Python 3
เนื่องจากข้อมูลข้างต้นไม่สามารถใช้งานได้ใน Python 3 คุณสามารถทำได้แทน (อีกครั้งโดยไม่ต้องนำเข้าsys):

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

install_xxx()
print("[DONE]")

ฟังก์ชั่นการพิมพ์ยอมรับพารามิเตอร์ที่เริ่มต้นที่end "\n"การตั้งค่าเป็นสตริงว่างจะป้องกันไม่ให้มีการสร้างบรรทัดใหม่ที่ท้ายบรรทัด


1
มันทำงานได้อย่างสมบูรณ์ ได้เห็นเพียงโซลูชัน stdout เท่านั้น ดีจริง ๆ ที่รู้ว่า
โพร

5
สิ่งนี้จะไม่ทำงานหากคุณมีทั้งงานพิมพ์และการดำเนินการที่ต้องใช้เวลานานในระหว่าง (ทั้งหมดอยู่ในระดับฟังก์ชั่น / การเยื้องเดียวกัน) ก่อนที่การดำเนินการจะเริ่มไม่มีผลลัพธ์เลยและหลังจากเสร็จสิ้นผลลัพธ์จะปรากฏขึ้นทั้งหมด
Paddre

2
นั่นอาจเป็นหน้าที่ของการบัฟเฟอร์เอาต์พุตที่ preformed โดย OS สำหรับกระบวนการโดยรวมซึ่งไม่ใช่ปัญหาเฉพาะของงูหลาม ดูstackoverflow.com/questions/107705สำหรับวิธีแก้ปัญหาเฉพาะของ python
หลายหน้า

13
หากไม่มีบรรทัดใหม่คุณอาจต้องการล้างบัฟเฟอร์อย่างชัดเจน ใช้print("...", end="", flush=True)ใน Python 3 ใน Python 2 เพิ่มการsys.stdout.flush()โทร
Martijn Pieters

7
ใน python 3.x คุณจะต้องเพิ่ม "\ r" เพื่อสิ้นสุดเพื่อแทนที่บรรทัดที่พิมพ์ VS ผนวกท้ายของมันprint("Progress: {}%".format(var), end="\r", flush=True)
John

103

คุณสามารถใช้สิ่งนี้:

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

และผลลัพธ์จะเป็น

something else

ไม่จำเป็นต้อง overkill import sysโดย ใส่ใจกับสัญลักษณ์เครื่องหมายจุลภาคในตอนท้าย

Python 3+ print("some string", end="");เพื่อลบการขึ้นบรรทัดใหม่ที่ส่วนท้าย อ่านเพิ่มเติมโดยhelp(print);


3
โปรดทราบว่ามีช่องว่างสองช่องโดยใช้วิธีนี้
ethanjyx

1
นี่คือคำตอบที่ง่ายที่สุดและมีประสิทธิภาพมากที่สุด
gixxer

สิ่งนี้ไม่ทำงานเมื่อข้อโต้แย้งของการพิมพ์อยู่ในวงเล็บ ใช้งานได้: <พิมพ์ "hello",; พิมพ์ ("hello")> แต่มันใช้งานไม่ได้ <print ("hello",); พิมพ์ ("สวัสดี")>
Mayank Jaiswal

@ MayankJaiswal สิ่งนี้ใช้ได้กับ parens พิมพ์ ('hello'),
drglove

1
printฟังก์ชั่นมีไวยากรณ์ที่แตกต่างกันเล็กน้อยใน python 2 VS 3
boldnik

52

คุณควรใช้ backspace ' \ r ' หรือ (' \ x08 ') ถ่านเพื่อกลับไปที่ตำแหน่งก่อนหน้าในเอาต์พุตคอนโซล

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

รหัสนี้จะนับจาก 0% ถึง 100% ในหนึ่งบรรทัด ค่าสุดท้ายจะเป็น:

> python test.py
100%

ข้อมูลเพิ่มเติมเกี่ยวกับ flush ในกรณีนี้ที่นี่: ทำไม python print statement ที่มีอาร์กิวเมนต์ 'end =' ทำงานต่างกันใน while-loops?


1
เพื่อให้ชัดเจนขึ้นดูเหมือนว่าโค้ดที่ใส่ความคิดเห็นในตัวอย่างนี้มีไว้สำหรับ Python 2 และบรรทัดที่ไม่มีความคิดเห็นสำหรับ Python 3
เต่าน่ารัก

1
บรรทัด bouth จะทำงานได้ดีใน Python 3 หากคุณใช้ '\ x08' เป็น backspace คุณต้องล้างเอาต์พุตสตรีม - พิมพ์ ((b '\ x08' * n) .decode (), end = '', flush = จริง)
Vadim Zin4uk

1
การคืนค่าขนส่ง '\ r' กลับไปที่จุดเริ่มต้นของบรรทัดดังนั้น '* n' จึงไม่จำเป็น
bjnortier

43

การใช้งานและsys.stdout.write('Installing XXX... ') sys.stdout.write('Done')ด้วยวิธีนี้คุณจะต้องเพิ่มบรรทัดใหม่ด้วยมือ"\n"หากคุณต้องการสร้างฟังก์ชันการพิมพ์ใหม่ ฉันคิดว่ามันอาจไม่จำเป็นที่จะใช้คำสาปเพียงแค่นี้


4
ฉันเองชอบวิธีนี้มากกว่าวิธีที่ได้คะแนนสูงกว่าเพราะมันทำงานในแบบเดียวกันกับ python2.x และ python3.x โดยไม่จำเป็นต้องพึ่งพา__future__การนำเข้าหรืออะไรทำนองนั้น
mgilson

17

ไม่มีคำตอบใดที่เหมาะกับฉันตั้งแต่หยุดชั่วคราวจนกระทั่งพบบรรทัดใหม่ ฉันเขียนผู้ช่วยอย่างง่าย:

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

เพื่อทดสอบ:

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

"สวัสดี" ก่อนจะพิมพ์ออกมาและล้างไปที่หน้าจอก่อนนอน หลังจากนั้นคุณสามารถใช้การพิมพ์มาตรฐาน


1
ขอบคุณ! สิ่งที่ฉันต้องการคือ aka .flush ()
MrNice


11

ง่ายที่สุด:

Python 3

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

มันหมายความว่ามันจะกลับเคอร์เซอร์ไปที่จุดเริ่มต้นกว่าจะพิมพ์บางสิ่งและจะสิ้นสุดในบรรทัดเดียวกัน หากวนซ้ำก็จะเริ่มพิมพ์ในที่เดียวกับที่เริ่มต้น


3
เย็น! ทำงานได้ใน Windows เช่นกัน
Shital Shah

2
ขอบคุณมันใช้งานได้ดีสำหรับฉัน! ฉันคิดว่าprint(’something to be override’, end=‘\r’)มันง่ายกว่า
Tropilio


9

พิมพ์มีendอาร์กิวเมนต์ตัวเลือกมันเป็นสิ่งที่พิมพ์ในตอนท้าย ค่าเริ่มต้นคือขึ้นบรรทัดใหม่ แต่คุณสามารถเปลี่ยนเป็นสตริงว่างได้ เช่นprint("hello world!", end="")


2
นี่คือในหลาม 3. ในหลาม 2 print 'something',คุณสามารถเพียงแค่ เครื่องหมายจุลภาคที่ท้ายป้องกันการเพิ่มขึ้นบรรทัดใหม่
arjoonn

4

หากคุณต้องการเขียนทับบรรทัดก่อนหน้า (แทนที่จะเพิ่มเข้าไปอย่างต่อเนื่อง) คุณสามารถรวม\rกับ print(),ท้ายคำสั่งการพิมพ์ ตัวอย่างเช่น,

from time import sleep

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

print("...DONE!")

จะนับ 0 ถึง 9 แทนที่หมายเลขเดิมในคอนโซล "...DONE!"จะพิมพ์ในบรรทัดเดียวกันเป็นเคาน์เตอร์ที่ผ่านมา 9

ในกรณีของคุณสำหรับ OP สิ่งนี้จะอนุญาตให้คอนโซลแสดงเปอร์เซ็นต์การติดตั้งทั้งหมดเป็น "แถบความคืบหน้า" ซึ่งคุณสามารถกำหนดตำแหน่งเริ่มต้นและสิ้นสุดของอักขระและอัปเดตเครื่องหมายในระหว่างนั้น

print("Installing |XXXXXX              | 30%"),

4

นี่คือรุ่นที่เข้ากันได้ 2.7 ที่ได้รับมาจากรุ่น 3.0 โดย @ 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)

สำหรับเรื่องนั้นโซลูชัน 3.0 ที่ให้มานั้นดูค่อนข้างป่อง ตัวอย่างเช่นวิธีการ backspace ไม่ได้ใช้ประโยชน์จากอาร์กิวเมนต์จำนวนเต็มและอาจจะทำได้ด้วยกันโดยสิ้นเชิง

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

ทั้งสองได้รับการทดสอบและทำงาน


2

นี่เป็นเธรดที่เก่ามาก แต่นี่เป็นคำตอบและตัวอย่างโค้ดอย่างละเอียด

\rคือการแสดงสตริงของCarriage Returnจากชุดอักขระ ASCII มันเป็นเช่นเดียวกับฐานแปด015[ chr(0o15)] หรือ hexidecimal 0d[ chr(0x0d)] หรือทศนิยม13[ chr(13)] ดูman asciiการอ่านที่น่าเบื่อ มัน ( \r) เป็นการนำเสนอแบบพกพาที่สวยและง่ายสำหรับผู้อ่าน มันง่ายมากที่จะเคลื่อนย้ายแคร่บนเครื่องพิมพ์ดีดไปจนถึงจุดเริ่มต้นโดยไม่ต้องเลื่อนกระดาษ เป็นCRส่วนCRLFที่หมายถึงCarriage Return และ Line Feedกลับบินและสายฟีด

print()เป็นฟังก์ชั่นใน Python 3 ใน Python 2 (เวอร์ชันใด ๆ ที่คุณสนใจจะใช้) printสามารถบังคับเข้าฟังก์ชั่นได้โดยการนำเข้าคำจำกัดความของมันจาก__future__โมดูล ประโยชน์ของprintฟังก์ชั่นคือคุณสามารถระบุสิ่งที่จะพิมพ์ในตอนท้ายเอาชนะพฤติกรรมเริ่มต้นของ\nการพิมพ์ขึ้นบรรทัดใหม่ในตอนท้ายของทุกprint()สาย

sys.stdout.flushบอก Python ให้ล้างเอาต์พุตของเอาต์พุตมาตรฐานซึ่งเป็นตำแหน่งที่คุณส่งเอาต์พุตด้วยprint()เว้นแต่คุณจะระบุเป็นอย่างอื่น คุณยังสามารถรับลักษณะการทำงานเดียวกันได้โดยการรันpython -uหรือการตั้งค่าตัวแปรสภาพแวดล้อมPYTHONUNBUFFERED=1ดังนั้นการข้ามimport sysและการsys.stdout.flush()โทร จำนวนเงินที่คุณได้รับจากการทำเช่นนั้นเกือบเป็นศูนย์และไม่ใช่เรื่องง่ายที่จะทำการดีบั๊กถ้าคุณลืมว่าคุณต้องทำตามขั้นตอนนั้นก่อนที่ใบสมัครของคุณจะทำงานอย่างถูกต้อง

และเป็นตัวอย่าง โปรดทราบว่าสิ่งนี้ทำงานได้อย่างสมบูรณ์ใน Python 2 หรือ 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()

ฉันคิดว่าคำตอบของคุณเหมาะสมกว่าสำหรับ: stackoverflow.com/questions/45263205/…
Marc Cayuela Rafols

2

print () มีพารามิเตอร์ในตัว "end" ที่ถูกตั้งค่าเป็น "\ n" Calling print ("This is America") กำลังเรียกการพิมพ์ ("This is America", end = "\ n") วิธีง่ายๆในการโทรคือพิมพ์ ("นี่คืออเมริกา", end = "")


1

ในกรณีที่คุณเก็บค่าไว้ล่วงหน้าในอาเรย์คุณสามารถเรียกมันในรูปแบบต่อไปนี้:

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

1

Python ต่อท้ายบรรทัดใหม่เพื่อสิ้นสุดการพิมพ์ ใช้ end = '' สำหรับ python3 สำหรับวิธีการพิมพ์เพื่อเพิ่มช่องว่างแทนการขึ้นบรรทัดใหม่ สำหรับ python2 ใช้เครื่องหมายจุลภาคเมื่อสิ้นสุดคำสั่งพิมพ์

print("Foo",end=' ')
print('Bar')

0

พบโพสต์ Quoraนี้ด้วยตัวอย่างที่ใช้งานได้สำหรับฉัน (python 3) ซึ่งใกล้เคียงกับสิ่งที่ฉันต้องการมากที่สุด (เช่นลบบรรทัดก่อนหน้าทั้งหมด)

ตัวอย่างที่พวกเขาให้:

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

สำหรับการพิมพ์บนบรรทัดเดียวกันตามที่คนอื่นแนะนำให้ใช้ end=""


-2

ฉันพบโซลูชันนี้และทำงานกับ 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

1
นั่นprintคือไวยากรณ์ที่ไม่ถูกต้องสำหรับ Python 2.7 และรหัสไม่ทำงานแม้ว่าจะมีไวยากรณ์ที่ถูกต้อง
Cory Madden
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.