前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一日一技:命令行进度条是什么原理?

一日一技:命令行进度条是什么原理?

作者头像
青南
发布2021-11-19 11:38:22
9130
发布2021-11-19 11:38:22
举报
文章被收录于专栏:未闻Code

摄影:产品经理

这个饭吃起来有点油

今年4月份,我写了一篇文章:字符串离奇消失之谜,有同学在评论里面问我:

\r有什么用?我们今天就来看看,如何使用\r来实现一个简易的命令行进度条。运行效果如下面这个动图所示:

这个SimpleProcessBar是怎么实现的呢?其实它的代码非常简单:

代码语言:javascript
复制
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')。其它代码都是辅助这一行的。我们试一试直接手动执行一下:

代码语言:javascript
复制
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会让输出光标回到行首,所以又会重新打印进度条,于是就形成了进度条更新的效果。

END

一二线大厂在职员工

十多年码龄的编程老鸟

国内外高校在读学生

中小学刚刚入门的新人

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-11-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 未闻Code 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档