web-dev-qa-db-ja.com

前の出力を上書きする同じ行への出力? python(2.5)

単純な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...   

しかしこの行を印刷し、次回に再印刷/更新して、一度だけ表示し、そのダウンロードの進行状況を確認したい...

どうすればできますか?

83
Kristian

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
147
Kudzu

1行変更するだけの場合は、\rを使用します。 \rは復帰を意味します。その効果は、キャレットを現在の行の先頭に戻すことだけです。何も消去されません。同様に、\bを使用して1文字後ろに移動できます。 (一部の端末はこれらの機能をすべてサポートしていない場合があります)

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)
36
Sam Dolan

curses module documentationcurses module 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()
17

テキストのブロックを再印刷できる私の小さなクラスです。前のテキストが適切に消去されるため、混乱を招くことなく、古いテキストを短い新しいテキストで上書きできます。

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")
9
Bouke Versteegh

python 2.7の簡単なprintステートメントの場合、'\r'の後にカンマを付けるだけです。

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

これは、他のPython 3以外のソリューションよりも短くなりますが、保守がより難しくなります。

7
Matt Ellen

文字列の末尾に「\ r」を追加し、印刷機能の末尾にカンマを追加するだけです。例えば:

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

スパイダー3.3.1-Windows 7-python 3.6を使用していますが、フラッシュは必要ありません。この投稿に基づいて- 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()
2
JoePythonKing

pythonの前の行を上書きするには、end = '\ r'をprint関数に追加して、この例をテストします。

import time
for j in range(1,5):
   print('waiting : '+j, end='\r')
   time.sleep(1)
0