推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
boell
V2EX  ›  Python

初学者求助,关于转义符 \b

  •  
  •   boell · Jan 18, 2021 · 3797 views
    This topic created in 1946 days ago, the information mentioned may be changed or developed.

    在 vs code 中,运行以下 py 文件: print('aaa\b\b\b') 终端输出‘aaa’三个字符。

    如果把代码改成: print('aaa\b\b\b',end='') 则什么都不输出(或者说先输出 aaa,然后被退格删除了)

    这里面的逻辑如何理解?

    22 replies    2021-01-19 12:42:05 +08:00
    imn1
        1
    imn1  
       Jan 18, 2021
    你不是都理解了么?你想问什么?
    est
        2
    est  
       Jan 18, 2021
    这个不是 python 问题。是 终端 的显示问题。。

    你执行 python 的时候改成 python xxxx.py | xxd 看下二进制输出就明白了。
    boell
        3
    boell  
    OP
       Jan 18, 2021
    @imn1
    我就是没明白啊!按我理解,\b 只是退格,本身没有删除功能。print('aaa\b\b\b') 就是先输出 aaa,光标再退 3 格,然后换行,所以最终输出 aaa 。按照这个理解,print('aaa\b\b\b',end='') 也应该输出 aaa 啊,怎么都被清除了?
    boell
        4
    boell  
    OP
       Jan 18, 2021
    @est
    不是很明白你说的二进制输出。我只会 python xxx.py 2>&1 | tee a.log 这样的写法。
    kxuanobj
        5
    kxuanobj  
       Jan 18, 2021
    @boell 少加一个\b 你就知道了
    boell
        6
    boell  
    OP
       Jan 18, 2021
    @kxuanobj
    少一个\b,仍然输出 aaa,这个我能理解啊。
    renmu123
        7
    renmu123  
       Jan 18, 2021 via Android
    用 cmd 打开 ipython,两者都输出 aaa
    canwushuang
        8
    canwushuang  
       Jan 18, 2021
    print 输出“光标”前面的内容,加入 end 参数则输出拼接内容。\b 即光标退格。
    canwushuang
        9
    canwushuang  
       Jan 18, 2021
    By default, the value of the 'end' parameter is '\n'.
    araraloren
        10
    araraloren  
       Jan 18, 2021
    这东西跟你用的终端有关系。。
    cmd 的话 都输出 aaa,只不过第二种没有换行
    ps 的话第二种没输出
    AoEiuV020
        11
    AoEiuV020  
       Jan 18, 2021
    还真没注意过这个,总之和 python,直接 shell 情况也一样,想了解应该看终端 terminal 源码,可能有什么相关规范,
    gyf304
        12
    gyf304  
       Jan 18, 2021
    Backspace (BS) 是一个 ASCII 字符 这个现象和 python 半毛钱关系都没有
    Backspace 是由 Terminal 处理的,python 单纯只是把这些字符输出到终端上了

    所以你的问题应该是:为什么我的终端接收到 'aaa\b\b\b\n' 输出 'aaa',但是接收到 'aaa\b\b\b' 什么都不输出

    我觉得你不用太纠结这些问题 真要纠结的话可以参考 https://zh.wikipedia.org/wiki/ANSI%E8%BD%AC%E4%B9%89%E5%BA%8F%E5%88%97
    AoEiuV020
        13
    AoEiuV020  
       Jan 18, 2021
    试了试,按我理解,输出都一样输出了,
    只不过没有换行的情况下一条命令的 Prompt 会覆盖退格键之后的内容,
    换行的话,Prompt 就打印在下一行了,不影响上一行退格的文字,
    bleepbloop
        14
    bleepbloop  
       Jan 18, 2021
    print('aaa\b\b\b',end='') 输出: aaa
    print('aaa\b\b\b',end=' ') 输出: aa
    print('aaa\b\b\b',end=' ') 输出: a
    print('aaa\b\b\b',end=' ') 输出:
    evadegame
        15
    evadegame  
       Jan 18, 2021   ❤️ 1
    '\b' 一般只能退格,不带删除功能。要实现删除效果需要输出 "\b \b", 先退格,然后打印空格,然后再退格。
    evadegame
        16
    evadegame  
       Jan 18, 2021
    print("aaa\b\b\b", end='') 会先打印 aaa,然后终端会从一行开头打印一些字符覆盖 aaa,如果你的 aaa...和\b\b\b...足够长,还可以看到没被覆盖的内容。
    Pagliacii
        17
    Pagliacii  
       Jan 18, 2021
    你可以简单地做个试验就知道了,代码如下图:

    ![image.png]( https://i.loli.net/2021/01/18/HkvliUAIu1CMrxg.png)
    Pagliacii
        18
    Pagliacii  
       Jan 18, 2021   ❤️ 1
    @Pagliacii #17 Backspace ("\b") 的作用是把光标往回退,来自于控制打印机的打印头回退的行为。而 Newline ("\n") 则是把光标移动到下一行。

    至于你的问题则是,没有 Newline 的输出时,光标在 "aaa" 的前边。而后续的终端提示字符就在目前光标所在位置输出了,从而导致 "aaa" 被提示字符给覆盖了。

    而有 Newline 时,由于光标此时位于 "aaa" 的下一行,终端提示字符输出时就不会覆盖 "aaa" 了
    XIVN1987
        19
    XIVN1987  
       Jan 18, 2021   ❤️ 1
    我觉得楼上 @evadegame @Pagliacii 说的是对的

    关键就是\b 只退格、不删除,,试下 print('aaaaaa\b\b\b\b\b\b',end='')会发现,,输出是“>>> aa”,就是因为退格到了行首,然后输出了“>>> ”四个字符把前四个 a 给覆盖了,,就只剩下了最后两个 a 了
    Pagliacii
        20
    Pagliacii  
       Jan 18, 2021
    @Pagliacii #18 这里的“打印机”应该是“打字机”
    boell
        21
    boell  
    OP
       Jan 18, 2021
    谢谢各位的热心帮助。试了下确实不同的终端有不同的处理方式。之前是在 vs code 里试的。在 ipython 中,输出 3 个 a ;在 IDLE 下,输出 3 个 a 和 3 个方框;在 python 自带的终端下,提示符 '>>> ' 会遮挡前 4 个字符,所以代码 print('aaaaa\b\b\b\b\b',end='') 会显示 1 个 a 。
    如果换成双字节的中文,情况更加复杂。比如 print('我是中国人\b\b\b\b\b',end='k'),有的会显示 “k 是中国人”,有的显示 “我是 k 国人”,我两台电脑上同样版本的 vs code 显示就不一样。
    no1xsyzy
        22
    no1xsyzy  
       Jan 19, 2021
    话说,有没有那种让终端内字符打印特别慢的工具?(管道工具?)那样或许可以方便理解
    ……
    好,现场做了一个
    https://gist.github.com/no1xsyzy/53f4f127f30a4c6b478b8e2a899e0b5a

    记得 chmod +x pipe-throttle.py
    然后 python3 -c 'print("aaa\b\b\b",end="")' | ./pipe-throttle.py 0.5
    就很清晰了。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2644 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 83ms · UTC 15:08 · PVG 23:08 · LAX 08:08 · JFK 11:08
    ♥ Do have faith in what you're doing.