前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python原地输出效果实现

Python原地输出效果实现

作者头像
用户7685359
发布2020-08-24 16:19:46
5750
发布2020-08-24 16:19:46
举报
文章被收录于专栏:FluentStudyFluentStudy

分享一个很有意思的代码,实现动画如下所示:

从有趣的代码中学习知识点

一、上代码

简单粗暴,直接上代码(代码来源于《fluent python》一书):

代码语言:javascript
复制
import threading
import itertools
import time
import sys


class Signal:
    """
    线程结束的标识
    """
    go = True


def spin(msg, signal):
    write, flush = sys.stdout.write, sys.stdout.flush

    for char in itertools.cycle('|/-\\'):
        status = char + ' ' + msg
        write(status)
        flush()
        write('\x08' * len(status))
        time.sleep(.1)

        if not signal.go:
            break

    write(' ' * len(status) + '\x08' * len(status))


def slow_function():
    # pretend wait IO a moment
    # 主线程 sleep ,子线程获得执行
    time.sleep(3)
    return 42


def supervisor():
    signal = Signal()
    spinner = threading.Thread(target=spin, args=('thinking!', signal))
    print('spinner object:', spinner)
    spinner.start()
    result = slow_function()
    signal.go = False
    spinner.join()
    return result


def main():
    result = supervisor()
    print('Answer:', result)


if __name__ == "__main__":
    main()

代码说明

代码中涉及到的小知识点,一一解释如下:

1、线程的切换

由于 GIL 的存在,所以每次只有一个线程在运行,所以 slow_function() 的作用就是强制 sleep 主线程,使子线程得到执行

2、sys.stdout.write 与 print 的区别,以及 sys.stdout.flush 的作用

来看下官方说明:

代码语言:javascript
复制
sys.stdout.write(string)
"""
  Write string to stream.
  Returns the number of characters written (which is always equal to the length of the string).

"""
print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
"""  
    Prints the values to a stream, or to sys.stdout by default.
    Optional keyword arguments:
    file:  a file-like object (stream); defaults to the current sys.stdout.
    sep:   string inserted between values, default a space.
    end:   string appended after the last value, default a newline.
    flush: whether to forcibly flush the stream.
"""

简单说下这几点区别:

a、sys.stdout.write 是只能将 string 写到流,并且返回 string 的长度,它总是与 string 的长度值完全一致

b、sys.stdout.write 只能输出单个 string,而 print 可以输出多个,多个之间默认用空格隔开,同时默认以换行符结尾,通过修改 sep 参数与 end 参数,可以改变间隔符和结束符

c、print 接受多个参数,其实 file 是一个 file-like 的对象,即必须要有 write(string) 方法,file 的默认值是 sys.stdout

d、print 还可写入文件

e、print 从 3.3 版本开始,接受 flush 的参数,默认值为 False

3、itertools.cycle(iterable) 函数是怎么用的

这个就比较简单了,官方解释如下:

Make an iterator returning elements from the iterable and saving a copy of each. When the iterable is exhausted, return elements from the saved copy. Repeats indefinitely. Roughly equivalent to:

代码语言:javascript
复制
def cycle(iterable):
    # cycle('ABCD') --> A B C D A B C D A B C D ...
    saved = []
    for element in iterable:
        yield element
        saved.append(element)
    while saved:
        for element in saved:
              yield element

可以理解为无限循环可迭代对象里的元素

4、\x08 是个什么东西

这是个有意思的东西,从前面的动画可以看出,一直在动的光标是一直在首位的,但我们都知道输出会一直往后叠加。\x08 就是用来消除原来输出过的位置,\b也可以实现同样的效果

扩展

如何实现一个进度条的展示呢,效果是左侧有移动的进度条,右侧有固定的百分比?

这个代码后面在公开,感兴趣的可以在后台留言哦

你点的每个赞,我都认真当成了喜欢

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

本文分享自 FluentStudy 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、上代码
  • 代码说明
  • 扩展
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档