環境
- PC:windows10
- 言語 :python 3.6.7
概要
ただし,表示をするだけではなく,別スレッドの処理が完了したらdone表示,という内容にします.
コード
import threading
import time
import sys
class TestClass:
def __init__(self):
self.work_ended = False
def guruguru(self):
while not self.work_ended:
sys.stdout.write('\b' + '|')
sys.stdout.flush()
time.sleep(0.12)
sys.stdout.write('\b' + '/')
sys.stdout.flush()
time.sleep(0.12)
sys.stdout.write('\b' + '-')
sys.stdout.flush()
time.sleep(0.12)
sys.stdout.write('\b' + '\\')
sys.stdout.flush()
time.sleep(0.12)
sys.stdout.write('\b' + ' ') # 最後に末尾1文字を空白で書き換える
sys.stdout.flush()
def work(self):
time.sleep(3)
self.work_ended = True
def multithread_processing(self):
print("Collecting package metadata: ", end="")
t1 = threading.Thread(target=self.guruguru)
t2 = threading.Thread(target=self.work)
t1.start()
t2.start()
t2.join()
t1.join()
sys.stdout.write("\b" + "done")
sys.stdout.flush()
if __name__ == '__main__':
tc = TestClass()
tc.multithread_processing()
print() # 改行して終了
解説
multithread_processing()
最初にCollecting package metadata:
をコンソールに表示して,次に2つのスレッドを立てて,両方が完了したらdone
を表示しています.
guruguru()
名前通り,ぐるぐる棒を回します.
sys.stdout.write
+ sys.stdout.flush
の組み合わせで,コンソールに即時表示しています.
また,\b
でカーソルを1つ戻した後に文字を追加することで,コンソールに表示された既存の文字列の末尾だけを上書きしています.
work()
実用上はここに任意の作業を書きます.
上のコードでは3秒間スリープするだけの処理です.
あとがき
スレッドをデーモン化すれば,上のコードのwork_ended
のような条件を使わなくてもいいのではないかと思ったのですが,デーモンスレッドが終了するタイミングが調整しづらかったため,上のような書き方になりました.