zoukankan      html  css  js  c++  java
  • python的进度条实现

    进度条最主要的问题就是所有字符全部在同一行,而且可以修改。然而当执行print语句的时候,python会在打印完这个语句的同时,在结尾加上换行‘ ’,这就导致在控制台下一旦被print之后就无法修改了。

    我们需要使用的是来自sys.stdout.write()函数,这个函数会在控制台输出这个字符串的同时不加上任何结尾,这就意味着这个输出还没有完全结束。通过sys.stdout.flush()函数可以把输出暂时打印在控制台中(造成print的假象)。那么我们用‘ ’来回到行首。一切看起来那么简单了。

    也就是说:打印字符串的时候,没有加上' ',同时让光标回到行首,再把当前缓冲区显示出来,也就好像是print了一样,但是这时候光标还在原来位置。

    举个例子:

    import sys, time
    for i in range(10):
        sys.stdout.write('{0}/10
    '.format(i + 1))
        sys.stdout.flush()
        time.sleep(1)

    在终端下执行这段代码就会得到简单的进度效果。

    接下来需要解决两个问题:

    一、清空缓冲区:

    当新的字符串比之前短的时候会出现问题,如下:

    import sys, time
    for i in range(10):
        sys.stdout.write(str(i) * (10 - i) + '
    ')
        sys.stdout.flush()
        time.sleep(1)

    运行后会发现,结果跟期望的不一样。

    其实是因为已经被flush出去的字符并不会主动清空,所以只有新写入的被修改了。针对这点,我目前的解决方案是先输出一波空格,把之前的字符串冲掉,然后重写:

    import sys, time
    for i in range(10):
        sys.stdout.write(str(i) * (10 - i) + '
    ')
        sys.stdout.flush()
        time.sleep(1)

    二、固定底边输出:

    有时候我们希望在进度条加载的同时,还有一些其他输出。不妨在刷新掉上一次输出之后输出所需输出的字符串,然后在假输出进度条。如下:

    import sys, time
    for i in range(10):
        sys.stdout.write(' ' * 10 + '
    ')
        sys.stdout.flush()
        print(i)
        sys.stdout.write(str(i) * (10 - i) + '
    ')
        sys.stdout.flush()
        time.sleep(1)

    以后也可以给出一个自己实现的类来打印进度条:

    class Process(object):
        def __init__(self, id, wide=20):
            self.id = id
            self.wide = wide
    
        def log(self, line):
            info = self.id*line + '{0}%'.format(int(line/self.wide*100)) + '
    '
            sys.stdout.write(info)
            sys.stdout.flush()
            time.sleep(0.5)
    
    obj = Process('>>')
    for i in range(20):
        obj.log(i)
    进度条
     1 import sys, time
     2 
     3 
     4 class ProgressBar:
     5     def __init__(self, count=0, total=0, width=50):
     6         self.count = count
     7         self.total = total
     8         self.width = width
     9 
    10     def move(self):
    11         self.count += 1
    12 
    13     def log(self, s):
    14         sys.stdout.write(' ' * (self.width + 9) + '
    ')
    15         sys.stdout.flush()
    16         print(s)
    17         progress = self.width * self.count / self.total
    18         sys.stdout.write('{0:3}/{1:3}: '.format(self.count, self.total))
    19         sys.stdout.write('#' * int(progress) + '-' * int(self.width - progress) + '
    ')
    20         if progress == self.
    21             sys.stdout.write('
    ')
    22         sys.stdout.flush()
    23 
    24 
    25 bar = ProgressBar(total=10)
    26 for i in range(10):
    27     bar.move()
    28     bar.log('We have arrived at: ' + str(i + 1))
    29     time.sleep(1)
    进度条二
  • 相关阅读:
    vue获取下拉框值
    vue子父组件通信
    内存堆栈问题
    Object.defineProperty()--数据劫持原理
    call和apply和bind的区别
    Object.create()和new object()和{}的区别
    Object.keys()/Object.values()的简单理解
    object.assign
    泛型的定义、使用
    ts 泛型
  • 原文地址:https://www.cnblogs.com/caibao666/p/6805799.html
Copyright © 2011-2022 走看看