หากฉันมีรหัสต่อไปนี้:
for x in range(10):
print x
ฉันจะได้ผลลัพธ์ของ
1
2
etc..
สิ่งที่ฉันต้องการทำคือแทนที่จะพิมพ์ขึ้นบรรทัดใหม่ฉันต้องการแทนที่ค่าก่อนหน้าและเขียนทับด้วยค่าใหม่ในบรรทัดเดียวกัน
หากฉันมีรหัสต่อไปนี้:
for x in range(10):
print x
ฉันจะได้ผลลัพธ์ของ
1
2
etc..
สิ่งที่ฉันต้องการทำคือแทนที่จะพิมพ์ขึ้นบรรทัดใหม่ฉันต้องการแทนที่ค่าก่อนหน้าและเขียนทับด้วยค่าใหม่ในบรรทัดเดียวกัน
คำตอบ:
วิธีหนึ่งคือใช้'\r'อักขระreturn ( ) เพื่อกลับไปที่จุดเริ่มต้นของบรรทัดโดยไม่ต้องไปที่บรรทัดถัดไป:
for x in range(10):
print '{0}\r'.format(x),
print
เครื่องหมายจุลภาคท้ายคำสั่งพิมพ์จะบอกว่าไม่ต้องไปที่บรรทัดถัดไป คำสั่งพิมพ์ล่าสุดจะเลื่อนไปยังบรรทัดถัดไปดังนั้นข้อความแจ้งของคุณจะไม่เขียนทับผลลัพธ์สุดท้ายของคุณ
ตอนนี้ Python 2 เป็น EOL คำตอบของ Python 3 มีความหมายมากขึ้น สำหรับ Python 3.5 และรุ่นก่อนหน้า:
for x in range(10):
print('{}\r'.format(x), end="")
print()
ใน Python 3.6 และใหม่กว่าf-stringsอ่านได้ดีกว่า:
for x in range(10):
print(f'{x}\r', end="")
print()
%ดำเนินการเลิกใช้งานแล้ว โดยพื้นฐานแล้วสตริงทั้งหมดมีวิธีการจัดรูปแบบ ในกรณีนี้{0}หมายถึง "อาร์กิวเมนต์แรกถึงformat()" (การนับเริ่มต้นที่ 0)
re.sub(r'\$<\d+>[/*]?', '', curses.tigetstr('el') or '')จะให้สตริงการลบไปยังจุดสิ้นสุดของบรรทัดที่ถูกต้องสำหรับเทอร์มินัลที่ผู้ใช้มี อย่าลืมเริ่มต้นcursesด้วยสิ่งที่ต้องการcurses.setupterm(fd=sys.stdout.fileno())และใช้sys.stdout.isatty()เพื่อให้แน่ใจว่าเอาต์พุตของคุณไม่ถูกเปลี่ยนเส้นทางไปยังไฟล์ ดูcode.activestate.com/recipes/475116สำหรับโมดูล Python แบบเต็มพร้อมการควบคุมเคอร์เซอร์และการรองรับสี
import curses; curses.setupterm(fd=sys.stdout.fileno()); print(hex(curses.tigetstr('cr')));ควรพิมพ์รหัสฐานสิบหกของลำดับอักขระเพื่อไปที่จุดเริ่มต้นของบรรทัด
เนื่องจากฉันมาที่นี่ผ่าน Google แต่ฉันใช้ Python 3 นี่คือวิธีการทำงานใน Python 3:
for x in range(10):
print("Progress {:2.1%}".format(x / 10), end="\r")
คำตอบที่เกี่ยวข้องที่นี่: ฉันจะระงับการขึ้นบรรทัดใหม่หลังจากคำสั่งพิมพ์ได้อย่างไร?
testingและการวนซ้ำครั้งที่สองของคุณพิมพ์testผลลัพธ์หลังจากผ่านรอบที่สองจะยังคงเป็นtesting- ตอนนี้ฉันเห็นว่า @ Nagasaki45 ชี้สิ่งนี้
print("\r", message, end="")
คำตอบของ @Mike DeSimone อาจใช้งานได้เกือบตลอดเวลา แต่...
for x in ['abc', 1]:
print '{}\r'.format(x),
-> 1bc
เนื่องจากการ'\r'ย้อนกลับไปที่จุดเริ่มต้นของบรรทัดเท่านั้น แต่ไม่ได้ล้างเอาต์พุต
หากการสนับสนุน POSIX เพียงพอสำหรับคุณสิ่งต่อไปนี้จะล้างบรรทัดปัจจุบันและปล่อยเคอร์เซอร์ไว้ที่จุดเริ่มต้น:
print '\x1b[2K\r',
ใช้รหัสหนี ANSI เพื่อล้างสายเทอร์มินัล สามารถดูข้อมูลเพิ่มเติมได้ในวิกิพีเดียและในการพูดคุยที่ยอดเยี่ยมนี้
วิธีแก้ปัญหา (ไม่ดีนัก) ที่ฉันพบมีลักษณะดังนี้:
last_x = ''
for x in ['abc', 1]:
print ' ' * len(str(last_x)) + '\r',
print '{}\r'.format(x),
last_x = x
-> 1
ข้อดีอย่างหนึ่งคือมันจะทำงานบน windows ด้วย
ฉันมีคำถามเดียวกันก่อนเข้าชมกระทู้นี้ สำหรับฉัน sys.stdout.write ใช้งานได้ก็ต่อเมื่อฉันล้างบัฟเฟอร์เช่น
for x in range(10):
sys.stdout.write('\r'+str(x))
sys.stdout.flush()
ผลลัพธ์จะถูกพิมพ์เฉพาะในตอนท้ายของสคริปต์เท่านั้น
stringvar.ljust(10,' ')ในกรณีของสตริงที่มีความยาวผันแปรได้
\rปราบปรามการขึ้นบรรทัดใหม่และพิมพ์
print 1,
print '\r2'
หรือเขียนถึง stdout:
sys.stdout.write('1')
sys.stdout.write('\r2')
ลองสิ่งนี้:
import time
while True:
print("Hi ", end="\r")
time.sleep(1)
print("Bob", end="\r")
time.sleep(1)
มันได้ผลสำหรับฉัน end="\r"ส่วนหนึ่งคือการทำให้มันเขียนทับบรรทัดก่อนหน้า
คำเตือน!
หากคุณพิมพ์ออกมาจากhiนั้นพิมพ์helloโดยใช้\rคุณจะได้รับhilloเนื่องจากผลลัพธ์เขียนทับตัวอักษรสองตัวก่อนหน้า หากคุณพิมพ์hiโดยเว้นวรรค (ซึ่งไม่ปรากฏที่นี่) ระบบจะแสดงผลออกhiมา \rเพื่อแก้ไขปัญหานี้พิมพ์ออกมาโดยใช้ช่องว่าง
Hi BobHi BobHi BobHi BobHi Bobแต่การส่งออกของฉันคือ Python 3.7.1
\rอยู่ที่จุดเริ่มต้นแทนที่จะเป็นจุดสิ้นสุด
ฉันไม่สามารถหาวิธีแก้ปัญหาใด ๆ ในหน้านี้เพื่อใช้กับIPythonได้ แต่การเปลี่ยนแปลงเล็กน้อยในโซลูชันของ @ Mike-Desimone ได้ผล: แทนที่จะยุติบรรทัดด้วยการกลับแคร่ให้เริ่มบรรทัดด้วยการกลับแคร่:
for x in range(10):
print '\r{0}'.format(x),
นอกจากนี้วิธีนี้ไม่จำเป็นต้องใช้คำสั่งพิมพ์ครั้งที่สอง
for x in range(10):
time.sleep(0.5) # shows how its working
print("\r {}".format(x), end="")
time.sleep (0.5) คือการแสดงวิธีการลบเอาต์พุตก่อนหน้าและเอาต์พุตใหม่ถูกพิมพ์ "\ r" เมื่อเริ่มต้นข้อความการพิมพ์ระบบจะลบเอาต์พุตก่อนหน้านี้ออกก่อนเอาต์พุตใหม่
สิ่งนี้ใช้ได้กับ Windows และ python 3.6
import time
for x in range(10):
time.sleep(0.5)
print(str(x)+'\r',end='')
คำตอบที่ได้รับการยอมรับไม่สมบูรณ์แบบสมบูรณ์แบบบรรทัดที่พิมพ์ครั้งแรกจะอยู่ที่นั่นและหากงานพิมพ์ครั้งที่สองของคุณไม่ครอบคลุมบรรทัดใหม่ทั้งหมดคุณจะได้รับข้อความขยะ
เพื่อแสดงปัญหาให้บันทึกรหัสนี้เป็นสคริปต์และเรียกใช้ (หรือเพียงแค่ดู):
import time
n = 100
for i in range(100):
for j in range(100):
print("Progress {:2.1%}".format(j / 100), end="\r")
time.sleep(0.01)
print("Progress {:2.1%}".format(i / 100))
ผลลัพธ์จะมีลักษณะดังนี้:
Progress 0.0%%
Progress 1.0%%
Progress 2.0%%
Progress 3.0%%
สิ่งที่ได้ผลสำหรับฉันคือการล้างบรรทัดก่อนที่จะพิมพ์ถาวร อย่าลังเลที่จะปรับให้เข้ากับปัญหาเฉพาะของคุณ:
import time
ERASE_LINE = '\x1b[2K' # erase line command
n = 100
for i in range(100):
for j in range(100):
print("Progress {:2.1%}".format(j / 100), end="\r")
time.sleep(0.01)
print(ERASE_LINE + "Progress {:2.1%}".format(i / 100)) # clear the line first
และตอนนี้มันพิมพ์ตามที่คาดไว้:
Progress 0.0%
Progress 1.0%
Progress 2.0%
Progress 3.0%
นี่คือคำตอบ "Plug-and-play" ที่สะอาดกว่าและเป็นเวอร์ชั่นของ @ Nagasaki45 ซึ่งแตกต่างจากคำตอบอื่น ๆ ที่นี่ตรงนี้ทำงานได้ดีกับสตริงที่มีความยาวต่างกัน ทำได้โดยการล้างบรรทัดให้มีช่องว่างมากพอ ๆ กับความยาวของบรรทัดสุดท้ายที่พิมพ์ จะทำงานบน Windows
def print_statusline(msg: str):
last_msg_length = len(print_statusline.last_msg) if hasattr(print_statusline, 'last_msg') else 0
print(' ' * last_msg_length, end='\r')
print(msg, end='\r')
sys.stdout.flush() # Some say they needed this, I didn't.
print_statusline.last_msg = msg
เพียงใช้มันดังนี้:
for msg in ["Initializing...", "Initialization successful!"]:
print_statusline(msg)
time.sleep(1)
การทดสอบขนาดเล็กนี้แสดงให้เห็นว่าเส้นได้รับการล้างอย่างถูกต้องแม้จะมีความยาวต่างกัน:
for i in range(9, 0, -1):
print_statusline("{}".format(i) * i)
time.sleep(0.5)
ฉันแปลกใจเล็กน้อยที่ไม่มีใครใช้อักขระ backspace นี่คือสิ่งที่ใช้มัน
import sys
import time
secs = 1000
while True:
time.sleep(1) #wait for a full second to pass before assigning a second
secs += 1 #acknowledge a second has passed
sys.stdout.write(str(secs))
for i in range(len(str(secs))):
sys.stdout.write('\b')
sys.stdout.flush()
(Python3) นี่คือสิ่งที่ใช้ได้ผลสำหรับฉัน ถ้าคุณแค่ใช้ \ 010 มันจะเหลืออักขระดังนั้นฉันจึงปรับมันเล็กน้อยเพื่อให้แน่ใจว่ามันเขียนทับสิ่งที่มีอยู่ นอกจากนี้ยังช่วยให้คุณมีบางอย่างก่อนพิมพ์รายการแรกและลบเฉพาะความยาวของรายการเท่านั้น
print("Here are some strings: ", end="")
items = ["abcd", "abcdef", "defqrs", "lmnop", "xyz"]
for item in items:
print(item, end="")
for i in range(len(item)): # only moving back the length of the item
print("\010 \010", end="") # the trick!
time.sleep(0.2) # so you can see what it's doing
อีกหนึ่งคำตอบที่ขึ้นอยู่กับคำตอบทั่วไป
เนื้อหาของ pbar.py: import sys, shutil, datetime
last_line_is_progress_bar=False
def print2(print_string):
global last_line_is_progress_bar
if last_line_is_progress_bar:
_delete_last_line()
last_line_is_progress_bar=False
print(print_string)
def _delete_last_line():
sys.stdout.write('\b\b\r')
sys.stdout.write(' '*shutil.get_terminal_size((80, 20)).columns)
sys.stdout.write('\b\r')
sys.stdout.flush()
def update_progress_bar(current, total):
global last_line_is_progress_bar
last_line_is_progress_bar=True
completed_percentage = round(current / (total / 100))
current_time=datetime.datetime.now().strftime('%m/%d/%Y-%H:%M:%S')
overhead_length = len(current_time+str(current))+13
console_width = shutil.get_terminal_size((80, 20)).columns - overhead_length
completed_width = round(console_width * completed_percentage / 100)
not_completed_width = console_width - completed_width
sys.stdout.write('\b\b\r')
sys.stdout.write('{}> [{}{}] {} - {}% '.format(current_time, '#'*completed_width, '-'*not_completed_width, current,
completed_percentage),)
sys.stdout.flush()
การใช้สคริปต์:
import time
from pbar import update_progress_bar, print2
update_progress_bar(45,200)
time.sleep(1)
update_progress_bar(70,200)
time.sleep(1)
update_progress_bar(100,200)
time.sleep(1)
update_progress_bar(130,200)
time.sleep(1)
print2('some text that will re-place current progress bar')
time.sleep(1)
update_progress_bar(111,200)
time.sleep(1)
print('\n') # without \n next line will be attached to the end of the progress bar
print('built in print function that will push progress bar one line up')
time.sleep(1)
update_progress_bar(111,200)
time.sleep(1)
นี่คือทางออกของฉัน! Windows 10, Python 3.7.1
ฉันไม่แน่ใจว่าทำไมรหัสนี้ถึงใช้งานได้ แต่มันจะลบบรรทัดเดิมทั้งหมด ฉันรวบรวมจากคำตอบที่แล้ว คำตอบอื่น ๆ ก็จะกลับมาเส้นเริ่มต้น แต่ถ้าคุณมีสายสั้นหลังจากนั้นก็จะมีลักษณะ messed ขึ้นเหมือนจะกลายเป็นhellobyelo
import sys
#include ctypes if you're on Windows
import ctypes
kernel32 = ctypes.windll.kernel32
kernel32.SetConsoleMode(kernel32.GetStdHandle(-11), 7)
#end ctypes
def clearline(msg):
CURSOR_UP_ONE = '\033[K'
ERASE_LINE = '\x1b[2K'
sys.stdout.write(CURSOR_UP_ONE)
sys.stdout.write(ERASE_LINE+'\r')
print(msg, end='\r')
#example
ig_usernames = ['beyonce','selenagomez']
for name in ig_usernames:
clearline("SCRAPING COMPLETE: "+ name)
เอาต์พุต - แต่ละบรรทัดจะถูกเขียนใหม่โดยไม่มีข้อความเก่าแสดง:
SCRAPING COMPLETE: selenagomez
บรรทัดถัดไป (เขียนใหม่ในบรรทัดเดียวกัน):
SCRAPING COMPLETE: beyonce
ดีกว่าที่จะเขียนทับทั้งบรรทัดมิฉะนั้นบรรทัดใหม่จะผสมกับบรรทัดเก่าหากบรรทัดใหม่สั้นกว่า
import time, os
for s in ['overwrite!', 'the!', 'whole!', 'line!']:
print(s.ljust(os.get_terminal_size().columns - 1), end="\r")
time.sleep(1)
ต้องใช้columns - 1บน Windows