V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
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 · 2021-01-18 10:55:58 +08:00 · 2800 次点击
    这是一个创建于 1165 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

    这里面的逻辑如何理解?

    22 条回复    2021-01-19 12:42:05 +08:00
    imn1
        1
    imn1  
       2021-01-18 11:27:08 +08:00
    你不是都理解了么?你想问什么?
    est
        2
    est  
       2021-01-18 11:30:26 +08:00
    这个不是 python 问题。是 终端 的显示问题。。

    你执行 python 的时候改成 python xxxx.py | xxd 看下二进制输出就明白了。
    boell
        3
    boell  
    OP
       2021-01-18 13:00:00 +08:00
    @imn1
    我就是没明白啊!按我理解,\b 只是退格,本身没有删除功能。print('aaa\b\b\b') 就是先输出 aaa,光标再退 3 格,然后换行,所以最终输出 aaa 。按照这个理解,print('aaa\b\b\b',end='') 也应该输出 aaa 啊,怎么都被清除了?
    boell
        4
    boell  
    OP
       2021-01-18 13:01:11 +08:00
    @est
    不是很明白你说的二进制输出。我只会 python xxx.py 2>&1 | tee a.log 这样的写法。
    kxuanobj
        5
    kxuanobj  
       2021-01-18 13:07:49 +08:00
    @boell 少加一个\b 你就知道了
    boell
        6
    boell  
    OP
       2021-01-18 13:11:40 +08:00
    @kxuanobj
    少一个\b,仍然输出 aaa,这个我能理解啊。
    renmu123
        7
    renmu123  
       2021-01-18 13:17:24 +08:00 via Android
    用 cmd 打开 ipython,两者都输出 aaa
    canwushuang
        8
    canwushuang  
       2021-01-18 13:37:47 +08:00
    print 输出“光标”前面的内容,加入 end 参数则输出拼接内容。\b 即光标退格。
    canwushuang
        9
    canwushuang  
       2021-01-18 13:42:21 +08:00
    By default, the value of the 'end' parameter is '\n'.
    araraloren
        10
    araraloren  
       2021-01-18 13:51:36 +08:00
    这东西跟你用的终端有关系。。
    cmd 的话 都输出 aaa,只不过第二种没有换行
    ps 的话第二种没输出
    AoEiuV020
        11
    AoEiuV020  
       2021-01-18 14:20:07 +08:00
    还真没注意过这个,总之和 python,直接 shell 情况也一样,想了解应该看终端 terminal 源码,可能有什么相关规范,
    gyf304
        12
    gyf304  
       2021-01-18 14:23:18 +08:00
    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  
       2021-01-18 14:26:16 +08:00
    试了试,按我理解,输出都一样输出了,
    只不过没有换行的情况下一条命令的 Prompt 会覆盖退格键之后的内容,
    换行的话,Prompt 就打印在下一行了,不影响上一行退格的文字,
    bleepbloop
        14
    bleepbloop  
       2021-01-18 14:32:58 +08:00
    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  
       2021-01-18 14:43:39 +08:00   ❤️ 1
    '\b' 一般只能退格,不带删除功能。要实现删除效果需要输出 "\b \b", 先退格,然后打印空格,然后再退格。
    evadegame
        16
    evadegame  
       2021-01-18 14:47:30 +08:00
    print("aaa\b\b\b", end='') 会先打印 aaa,然后终端会从一行开头打印一些字符覆盖 aaa,如果你的 aaa...和\b\b\b...足够长,还可以看到没被覆盖的内容。
    Pagliacii
        17
    Pagliacii  
       2021-01-18 15:28:59 +08:00
    你可以简单地做个试验就知道了,代码如下图:

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

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

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

    关键就是\b 只退格、不删除,,试下 print('aaaaaa\b\b\b\b\b\b',end='')会发现,,输出是“>>> aa”,就是因为退格到了行首,然后输出了“>>> ”四个字符把前四个 a 给覆盖了,,就只剩下了最后两个 a 了
    Pagliacii
        20
    Pagliacii  
       2021-01-18 16:00:22 +08:00
    @Pagliacii #18 这里的“打印机”应该是“打字机”
    boell
        21
    boell  
    OP
       2021-01-18 16:20:57 +08:00
    谢谢各位的热心帮助。试了下确实不同的终端有不同的处理方式。之前是在 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  
       2021-01-19 12:42:05 +08:00
    话说,有没有那种让终端内字符打印特别慢的工具?(管道工具?)那样或许可以方便理解
    ……
    好,现场做了一个
    https://gist.github.com/no1xsyzy/53f4f127f30a4c6b478b8e2a899e0b5a

    记得 chmod +x pipe-throttle.py
    然后 python3 -c 'print("aaa\b\b\b",end="")' | ./pipe-throttle.py 0.5
    就很清晰了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   979 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 20:12 · PVG 04:12 · LAX 13:12 · JFK 16:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.