zoukankan      html  css  js  c++  java
  • 【Python】关于print()、sys.stdout、sys.stderr的一些理解

    print() 方法的语法:

    print(*objects, sep=' ', end='
    ', file=sys.stdout, flush=False)

    其中file = sys.stdout的意思是,print函数会将内容打印输出到标准输出流(即 sys.stdout),当然也可以自定义输出流:

    with open('test.log', 'a') as f:
        print('hello world!', file=f)
    # 内容输出到了test.log文件中,终端不会打印任何内容

    也可以输出到错误输出流sys.stderr

    import sys
    print('hello world!', file=sys.stderr)
    # 》》hello world!

    其实print函数的默认输出等价于sys.stdout.write(),只是print会自动换行,而stdout需要手动添加转义符" "

    import sys
    print('hello world!')
    # 》》hello world!
    sys.stdout.write('hello world!
    ')
    # 》》hello world!

    而print的输出是否被缓存通常决定于file,但如果flush参数值为True,流会被强制刷新(flush默认为false)。这里需要先看下缓冲是怎么回事

    类型说明输出情况
    满缓冲 I/O操作只有在缓冲区被填满之后才会进行 1.缓冲区满
    2.刷出数据flush
    3.关闭文件
    行缓冲 通常只有遇到换行符时,才会执行实际的I/O操作;但缓冲区满也会强制执行 1.遇到换行符
    2.缓冲区满
    3.刷出数据flush
    4.关闭文件
    无缓冲 不缓存,直接进行I/O操作 直接输出

    可以在Python3官方文档中查到:When interactive, stdout and stderr streams are line-buffered. 标准输出流stdout和错误输出流stderr是行缓冲
    那么当file = stdout或者file = stderr时会按照行缓冲的条件输出到终端,即需要满足以下其中一个条件才会显示打印内容:

    1. 遇到换行符' '
    2. 代码运行结束或缓冲区满
    3. flush = True

    现在终于可以看下摘自runoob.com的例子了,print()函数使用 flush 参数生成一个 Loading 的效果:

    import time
    
    print('---RUNOOB EXAMPLE : Loading 效果---')
    
    print('Loading', end='')
    for i in range(20):
        print('.', end='', flush=True)
        time.sleep(0.5)

    效果如下图:

    因为print使用end=' '去掉了换行,如果没有flush=True的话,程序将在最后一次性的打印出结果“Loading....................”

    根据前面讲述的等效关系,又写了两种方法来实现上面的效果

    第一种是通过sys.stdout.write()来实现:

    import sys
    import time
    
    sys.stdout.write('Loading')
    for i in range(20):
        sys.stdout.write('.')
        sys.stdout.flush()
        time.sleep(0.5)

    第二种是通过sys.stderr.write()来实现,但是差别来了,其实网上随便查下stderr,会发现大多说它是无缓冲的,据说是从3.7版本之后变成的行缓冲,我用3.7.6版本执行代码是行缓冲的效果,2.7.10版本确实是无缓冲的效果了

    import sys
    import time
    
    sys.stderr.write('Loading')
    for i in range(20):
        sys.stderr.write('.')
        time.sleep(0.5)

    无缓冲会直接输出,便用不着sys.stdout.flush()来强制刷新了

  • 相关阅读:
    (收藏)Wp7开发中文网站
    (收藏)Andriod中文翻译组
    (1) BlackBerry 环境的配置:安装standalone版的BlackBerry安装包
    (2)把BlackBerry作为插件安装到已有的Eclipse中
    (收藏)一个很不错的编程网站
    Android Architecture
    在Eclipse Android中设置模拟器屏幕大小
    (收藏)C#网站
    (Android) Binding to Data with AdapterView
    ListView 的理解
  • 原文地址:https://www.cnblogs.com/oyster25/p/12348148.html
Copyright © 2011-2022 走看看