이전 인쇄물을 stdout으로 덮어쓰는 방법은 무엇입니까?
만약 내가 다음 코드를 가지고 있다면:
for x in range(10):
print(x)
의 결과물을 얻을 것입니다.
1
2
etc..
제가 하고 싶은 것은 새 줄을 인쇄하는 것이 아니라 이전 값을 대체하여 같은 줄의 새 값으로 덮어쓰는 것입니다.
단순 버전
리턴을 입니다.'\r'
줄로 입니다.). 다음 줄로 이동하지 않고 줄의 시작으로 돌아가는 문자입니다.
파이썬 3
for x in range(10):
print(x, end='\r')
print()
Python 2.7과의 상위 호환
from __future__ import print_function
for x in range(10):
print(x, end='\r')
print()
파이썬 2.7
for x in range(10):
print '{}\r'.format(x),
print
Python 2.0-2.6
for x in range(10):
print '{0}\r'.format(x),
print
후자의 두 개의 경우(Python 2-only) 인쇄 문 끝에 있는 쉼표는 다음 행으로 가지 말라고 말합니다.마지막 인쇄 문이 다음 행으로 이동하므로 프롬프트가 최종 출력을 덮어쓰지 않습니다.
라인 청소
수 " of line" 시퀀스인 " to end"를만 하면 .'\x1b[1K'
('\x1b'
ESC):
for x in range(75):
print('*' * (75 - x), x, end='\x1b[1K\r')
print()
구글을 통해 여기까지 왔지만 Python 3을 사용하고 있기 때문에, Python 3에서 이것이 어떻게 작동하는지는 다음과 같습니다.
for x in range(10):
print("Progress {:2.1%}".format(x / 10), end="\r")
관련 답변:문을 인쇄한 후 새 줄을 표시하지 않으려면 어떻게 해야 합니까?
@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
한 가지 장점은 창에서도 작동한다는 것입니다.
이 스레드를 방문하기 전에 같은 질문이 있었습니다.저는 sys.stdout입니다.버퍼를 적절하게 플러시해야 write worked.
for x in range(10):
sys.stdout.write('\r'+str(x))
sys.stdout.flush()
플러시하지 않고 스크립트의 마지막 부분에만 결과가 인쇄됩니다.
바꿈을 새쇄줄 표 함 및 인\r
.
print 1,
print '\r2'
또는 stdout에 씁니다.
sys.stdout.write('1')
sys.stdout.write('\r2')
for x in range(10):
time.sleep(0.5) # shows how its working
print("\r {}".format(x), end="")
time.sleep(0.5)은 메시지 인쇄 시작 시 이전 출력이 지워지고 새 출력이 "\r" 인쇄되는 방법을 보여줍니다. 새 출력 전에 이전 출력이 지워집니다.
사용해 보십시오.
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
.
여기 @나가사키45의 대답을 더 깨끗하고 더 "플러그 앤 플레이" 버전이 있습니다.여기에 나와 있는 다른 많은 답변과 달리 길이가 다른 문자열에서 올바르게 작동합니다.마지막 줄 인쇄 길이만큼 공백이 있는 줄을 지우면 됩니다.Windows에서도 작동합니다.
def print_statusline(msg: str):
last_msg_length = len(getattr(print_statusline, 'last_msg', ''))
print(' ' * last_msg_length, end='\r')
print(msg, end='\r')
sys.stdout.flush() # Some say they needed this, I didn't.
setattr(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)
Windows 및 Python 3.6에서 작동합니다.
import time
for x in range(10):
time.sleep(0.5)
print(str(x)+'\r',end='')
이 페이지의 솔루션을 IPython에서 사용할 수는 없었지만, @Mike-Desimone의 솔루션을 약간 변형시켜 사용했습니다. 캐리지 리턴으로 라인을 종료하는 대신 캐리지 리턴으로 라인을 시작하십시오.
for x in range(10):
print '\r{0}'.format(x),
또한 이 방법은 두 번째 인쇄문을 필요로 하지 않습니다.
승인된 답변이 완벽하지 않습니다.처음에 인쇄된 줄은 그대로 유지되며 두 번째 인쇄가 새 줄 전체를 덮지 않으면 가비지 텍스트가 표시됩니다.
문제를 설명하려면 이 코드를 스크립트로 저장하고 실행합니다(또는 보기만 하면 됩니다).
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%
저는 아무도 백스페이스 캐릭터를 사용하지 않는다는 것이 조금 놀랍습니다.여기 그것을 사용하는 것이 있습니다.
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')
내 해결책이 여기 있습니다!Windows 10, Python 3.7.1
왜 이 코드가 작동하는지는 잘 모르겠지만, 원래 라인을 완전히 지웁니다.저는 이전 답변에서 그것을 정리했습니다.다른 답들은 그냥 처음으로 줄을 되돌리지만, 나중에 줄이 더 짧으면 이렇게 엉망으로 보일 것입니다.hello
로 변하다.byelo
.
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
(파이썬3)이것이 저에게 효과가 있었습니다.그냥 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: 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)
전체 줄을 덮어쓰는 것이 좋습니다. 그렇지 않으면 새 줄이 더 짧으면 새 줄이 이전 줄과 혼합됩니다.
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(윈도우).
이것은 Windows에서 Spyder의 Python 3.7.9를 사용하여 작동했습니다.
from IPython.display import clear_output
from time import sleep
def print_and_overwrite(text):
'''Remember to add print() after the last print that you want to overwrite.'''
clear_output(wait=True)
print(text, end='\r')
for i in range(15):
#I print the results backwards (from 15 to 1), to test shorter strings
message = "Iteration %d out of 15" %(15-i)
print_and_overwrite(message)
sleep(0.5)
print() #This stops the overwriting
print("This will be on a new line")
어쨌든 누군가가 이전에 stdout에서 인쇄된 많은 줄을 다시 인쇄(지우기)하고 싶다면, 이 대답이 그에게 도움이 될 것입니다. (Thijmen Dam에게 이전에 인쇄된 줄 덮어쓰기).
ANSI 콘솔에서 특수 시퀀스를 사용할 수 있습니다.
\033[1A
그리고.\033[K
먼저 커서를 올리고, 두 번째로 선을 완전히 지웁니다.
콘솔 지우기 예제(Python 3):
LINE_UP = '\033[1A'
LINE_CLEAR = '\033[K'
CONSOLE_HEIGHT = 24 #lines
def clear_console():
for a in range(CONSOLE_HEIGHT):
print(LINE_UP, end=LINE_CLEAR, flush=True)
또는 결국 단순하게(화면을 지우고 커서를 0.0으로 이동):
print('\033[2J', end='', flush=True)
커서만 배치하려면 다음을 사용합니다.
print('\033[<L>;<C>f', end='', flush=True)
<L>
그리고.<C>
이에 상응하는 선과 열입니다.
ANSI 이스케이프 시퀀스에 대한 소수 참조
이 스레드에서 본 반응을 바탕으로 모든 플랫폼에서 좋을 수 있는 멋진 작은 클래스를 만들었습니다.
import sys
class PrintSameLine:
"""Class to correctly print on same line"""
def __init__(self):
self.last_message = ""
def print_msg(self, msg: str):
print(" " * len(self.last_message), end="\r", flush=True)
print(msg, end="\r", flush=True)
self.last_message = msg
# Note printing in reverse so you can see how it works
prnt = PrintSameLine()
for i in reverse(range(10)):
prnt.print_msg(str(i))
언급URL : https://stackoverflow.com/questions/5419389/how-to-overwrite-the-previous-print-to-stdout
'programing' 카테고리의 다른 글
MariaDB는 코드를 수동으로 실행해도 작동하는 구문 오류를 발생시키는 이유는 무엇입니까? (0) | 2023.06.14 |
---|---|
각도 - @입력 및 @출력 대주입식 서비스 (0) | 2023.06.14 |
C에서 EOF와 '\0'의 값은 무엇입니까? (0) | 2023.06.14 |
아이폰 데이터 사용량 추적/모니터링 (0) | 2023.06.14 |
사용자가 Firebase에서 로그아웃하도록 하는 방법은 무엇입니까? (0) | 2023.06.14 |