今年4月份,我写了一篇文章:字符串离奇消失之谜,有同学在评论里面问我:
\r
有什么用?我们今天就来看看,如何使用\r
来实现一个简易的命令行进度条。运行效果如下面这个动图所示:
这个SimpleProcessBar
是怎么实现的呢?其实它的代码非常简单:
import time class SimpleProcessBar: def __init__(self, total, finished='■', unfinished='□'): self.total = total self.finished = 0 self.unfinished_char = unfinished self.finished_char = finished self.bar = [self.unfinished_char] * 100 def incr(self, value=1): self.finished += value if self.finished > 100: self.finished = 100 bar = self.generate_bar() print(bar, end='\r') def generate_bar(self): finished = int(self.finished / self.total * 100) self.bar[:finished] = self.finished_char * finished return ''.join(self.bar) + f' {finished} %' x = SimpleProcessBar(30) for i in range(30): x.incr() time.sleep(1)
真正的核心代码就只有一行:print(bar, end='\r')
。其它代码都是辅助这一行的。我们试一试直接手动执行一下:
import time print("□" * 10, end='\r') time.sleep(1) print(f'{"■" * 3}{"□" * 7}', end='\r') time.sleep(1) print(f'{"■" * 6}{"□" * 4}', end='\r') time.sleep(1) print(f'{"■" * 9}{"□" * 1}', end='\r') time.sleep(1) print("■" * 10, end='\r')
运行效果如下所示:
因此,假设我们要画100个方块,那么,根据不同的进度,计算黑色实心方块的数量和白色空心方块的数量,然后把进度条的长字符串拼接起来,就可以打印了。
在默认情况下。print()
函数会默认给每个字符串末尾增加一个\n
换行符,所以我们每次使用print()
都会自动换行,如下图所示:
这个末尾添加的字符,是通过end
参数传入的。我们试一试更换成其它符号:
而根据本文开始引用的这篇文章的解释,\r
会让输出光标回到行首,所以又会重新打印进度条,于是就形成了进度条更新的效果。
请关注微信公众号【未闻Code】获取更多精彩文章。