初学者求助,关于转义符 \b - V2EX
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 3439 次点击
    这是一个创建于 1752 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在 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     Solana     5318 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 22ms UTC 07:42 PVG 15:42 LAX 23:42 JFK 02:42
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86