이전 출력을 덮어 쓰는 동일한 줄로 출력 하시겠습니까?


95

FTP 다운로더를 작성 중입니다. 코드의 일부는 다음과 같습니다.

ftp.retrbinary("RETR " + file_name, process)

콜백을 처리하기 위해 함수 프로세스를 호출하고 있습니다.

def process(data):
    print os.path.getsize(file_name)/1024, 'KB / ', size, 'KB downloaded!'
    file.write(data)

출력은 다음과 같습니다.

1784  KB / KB 1829 downloaded!
1788  KB / KB 1829 downloaded!
etc...   

하지만이 줄을 인쇄하고 다음에 다시 인쇄 / 새로 고침하여 한 번만 표시하고 해당 다운로드의 진행 상황을 볼 수 있도록합니다.

어떻게 할 수 있습니까?



답변:


185

다음은 Python 3.x 용 코드입니다.

print(os.path.getsize(file_name)/1024+'KB / '+size+' KB downloaded!', end='\r')

end=키워드 여기에 작업을 수행 무엇인가 - 기본적으로 print()줄 바꿈 (의 끝 \n) 문자는, 그러나 이것은 다른 문자열로 대체 할 수 있습니다. 이 경우 캐리지 리턴으로 줄을 끝내면 커서가 현재 줄의 시작 부분으로 돌아갑니다. 따라서 sys이러한 종류의 간단한 사용을 위해 모듈 을 가져올 필요가 없습니다 . print()실제로 코드를 크게 단순화하는 데 사용할 수 있는 여러 키워드 인수 가 있습니다.

Python 2.6 이상에서 동일한 코드를 사용하려면 파일 맨 위에 다음 줄을 추가합니다.

from __future__ import print_function

6
인쇄 기능은 파일 상단에 다음 가져 오기를 추가하여 Python 2.6 이상에서도 사용할 수 있습니다 from __future__ import print_function.
janin

12
파이썬 <3.0에서 명령문 끝에 쉼표가 print "foo",있으면 "\ n"이 방지됩니다. 그러나 변경 사항을 확인하려면 그 후에도 플러시해야합니다.sys.stdout.flush()
Tobias Domhan 2013-07-24

30
나는 \r문자열의 시작 부분에 를 포함하고 end=''대신 이것을 작동하도록 설정 해야한다는 것을 알았 습니다. 내가로 끝나는 때 내 단말기 좋아에게 그것을 생각하지 않는다\r
Jezzamon

2
현재의 모든 파이썬 3 버전에서는 추가 할 수 있습니다 flush=True받는 print()버퍼 (표준 라인은 A 완충액 플러시 것 플러시 수 있도록 기능을 \n개행 문자가 기록).
Martijn Pieters

4
jupyter 노트북 \r에서 처음 에는 사용 end=''하고 가장 원활하게 작동했습니다. 문자열과 함께 작동했지만 매끄럽지 않고 줄 및 줄 바꿈을 지우지 않은 경우 끝에 flush=Truewith \r를 사용 하십시오 end='\r'.
Dave X

40

한 줄만 변경하면 \r. \r캐리지 리턴을 의미합니다. 그 효과는 전적으로 현재 줄의 시작 부분에 캐럿을 다시 놓는 것입니다. 아무것도 지우지 않습니다. 마찬가지로 \b한 문자 뒤로 이동하는 데 사용할 수 있습니다. (일부 단말기는 이러한 모든 기능을 지원하지 않을 수 있습니다)

import sys

def process(data):
    size_str = os.path.getsize(file_name)/1024, 'KB / ', size, 'KB downloaded!'
    sys.stdout.write('%s\r' % size_str)
    sys.stdout.flush()
    file.write(data)

1
나는 그것이 \r캐리지 리턴 을 의미 한다고 덧붙일 것 입니다. 그 효과는 전적으로 현재 줄의 시작 부분에 캐럿을 다시 놓는 것입니다. 아무것도 지우지 않습니다. 마찬가지로 \b한 문자 뒤로 이동하는 데 사용할 수 있습니다. (일부 단말기는 이러한 모든 기능을 지원하지 않을 수 있음)
Adrien Plisson

sys.stdout.write('%s\r', size_str')당신이 의미하는 것 sys.stdout.write('%s\r' % size_str)같지만 작동하지 않습니다.
Kristian

@Adrien : 멋지네요. @Kristian : 감사합니다. 업데이트했습니다. 꽤 늦었습니다.
Sam Dolan

또한 원하는 경우 print대신 사용할 수 있습니다 . 잘 작동합니다. 인쇄 문장의 끝은 줄 바꿈을 억제; 여전히 필요sys.stdout.writeprint size_str + "\r",,sys.stdout.flush()
제프

19

curses 모듈 문서curses 모듈 HOWTO를 살펴보십시오 .

정말 기본적인 예 :

import time
import curses

stdscr = curses.initscr()

stdscr.addstr(0, 0, "Hello")
stdscr.refresh()

time.sleep(1)

stdscr.addstr(0, 0, "World! (with curses)")
stdscr.refresh()

10
불행히도 curses는 Unix에서만 사용할 수 있습니다. OP는 그의 응용 프로그램이 어떤 운영 체제를 목표로 삼고 있는지 알려주지 않았습니다.
Adrien Plisson

나는 리눅스에서 작업하는 데 너무 익숙해서 모듈 문서에서 모듈이 유닉스 전용이라는 경고도 눈치 채지 못했다. @Adrien.
Andrea Spadaccini

3
: @AdrienPlisson, 나는 당신이 실제로 Windows에 저주를 얻을 수 있습니다,이 질문은 년 전에 만들어 졌다고 알고 있지만 lfd.uci.edu/~gohlke/pythonlibs/#curses
콜드 Diamondz

이것을 파이썬 인터프리터에 붙여 넣었을 때 터미널이 푸바가되었습니다. 통역사에서 나가는 것은 도움이되지 않았습니다. WTF ?!
allyourcode

두 번째 줄이 첫 번째 줄보다 짧을 때 사용 clrtoeol합니다 .
Serge Stroobandt

9

다음은 텍스트 블록을 다시 인쇄 할 수있는 내 작은 수업입니다. 이전 텍스트를 제대로 지워서 엉망이되지 않고 더 짧은 새 텍스트로 이전 텍스트를 덮어 쓸 수 있습니다.

import re, sys

class Reprinter:
    def __init__(self):
        self.text = ''

    def moveup(self, lines):
        for _ in range(lines):
            sys.stdout.write("\x1b[A")

    def reprint(self, text):
        # Clear previous text by overwritig non-spaces with spaces
        self.moveup(self.text.count("\n"))
        sys.stdout.write(re.sub(r"[^\s]", " ", self.text))

        # Print new text
        lines = min(self.text.count("\n"), text.count("\n"))
        self.moveup(lines)
        sys.stdout.write(text)
        self.text = text

reprinter = Reprinter()

reprinter.reprint("Foobar\nBazbar")
reprinter.reprint("Foo\nbar")

2
이는 Windows 10까지의 Windows에서 작동하지 않습니다. Windows 10이 해당 제어 문자를 지원하는 최초의 창이기 때문입니다. en.wikipedia.org/wiki/ANSI_escape_code
user136036

8

python 2.7의 간단한 print 문의 경우 '\r'.

print os.path.getsize(file_name)/1024, 'KB / ', size, 'KB downloaded!\r',

이것은 다른 비 Python 3 솔루션보다 짧지 만 유지 관리가 더 어렵습니다.


1
Python 2.7.10이며 아무것도 인쇄하지 않습니다. 아마도 온라인으로 컴파일하여 작동 방식을 볼 수있는 링크를 보낼 수 있습니다 ...?
Shougo Makishima

5

문자열 끝에 '\ r'을 추가하고 인쇄 기능 끝에 쉼표를 추가 할 수 있습니다. 예를 들면 :

print(os.path.getsize(file_name)/1024+'KB / '+size+' KB downloaded!\r'),

1
이것은 파이썬 3 용입니까? 그렇다면 기본 end매개 변수를 \nso u print로 설정하면 어떨까요 (...)KB downloaded!\r\n? 내가 잘못?
SR

사용 end = '\r'파이썬 3의 문제를 대신하는 픽스
Abhimanyu 팔라 수 디르

4

나는 spyder 3.3.1-windows 7-python 3.6을 사용하고 있지만 flush가 필요하지 않을 수도 있습니다. 이 게시물을 기반으로-https: //github.com/spyder-ide/spyder/issues/3437

   #works in spyder ipython console - \r at start of string , end=""
import time
import sys
    for i in range(20):
        time.sleep(0.5)
        print(f"\rnumber{i}",end="")
        sys.stdout.flush()

1

파이썬에서 이전 줄을 덮어 쓰려면 인쇄 함수 에 end = '\ r' 을 추가하면됩니다. 다음 예제를 테스트하세요.

import time
for j in range(1,5):
   print('waiting : '+j, end='\r')
   time.sleep(1)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.