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
littleMaple
V2EX  ›  Python

Python 3.7 的内置 breakpoint() 函数如何 backport 到 3.6 中?

  •  
  •   littleMaple ·
    MapleCCC · 2021-02-08 01:47:12 +08:00 · 2670 次点击
    这是一个创建于 1369 天前的主题,其中的信息可能已经有所发展或是发生改变。

    一个简单的 backport 实现是:

    def breakpoint():
        import pdb
        pdb.set_trace()
    

    可是这样做和原生 breakpoint() 的行为并不完全一致,这样做虽然也能进入调试器,但是比原生 breakpoint() 多了一个栈帧。我尝试在 CPython 的源码中寻找 breakpoint() 的官方实现,无奈以失败告终,只找到了其单元测试 TestBreakpoint .

    25 条回复    2021-02-10 19:09:30 +08:00
    no1xsyzy
        1
    no1xsyzy  
       2021-02-08 09:26:29 +08:00   ❤️ 1
    # breakpointbackport.py

    def breakpoint():
       import pdb
       pdb.Pdb(skip=['breakpointbackport']).set_trace()
    ungrown
        2
    ungrown  
       2021-02-08 09:49:43 +08:00
    不用太纠结完全一致吧,够用就行了
    shniubobo
        3
    shniubobo  
       2021-02-08 10:01:07 +08:00 via Android   ❤️ 1
    XIVN1987
        4
    XIVN1987  
       2021-02-08 10:29:06 +08:00
    python 解释器交互太简陋了,,建议用 ipdb 进入 ipython

    import ipdb; ipdb.set_trace() # 设置断点

    class ExceptionHook: # 异常启动 ipython
    instance = None
    def __call__(self, *args, **kwargs):
    if self.instance is None:
    from IPython.core import ultratb
    self.instance = ultratb.FormattedTB(mode='Plain', color_scheme='Linux', call_pdb=1)
    return self.instance(*args, **kwargs)
    XIVN1987
        5
    XIVN1987  
       2021-02-08 10:29:44 +08:00
    python 解释器交互太简陋了,,建议用 ipdb 进入 ipython

    import ipdb; ipdb.set_trace() # 设置断点

    class ExceptionHook: # 异常启动 ipython
    instance = None
    def __call__(self, *args, **kwargs):
    if self.instance is None:
    from IPython.core import ultratb
    self.instance = ultratb.FormattedTB(mode='Plain', color_scheme='Linux', call_pdb=1)
    return self.instance(*args, **kwargs)
    XIVN1987
        6
    XIVN1987  
       2021-02-08 10:31:15 +08:00
    python 解释器交互太简陋了,,建议用 ipdb 进入 ipython

    ``` python
    import ipdb; ipdb.set_trace() # 设置断点

    class ExceptionHook: # 异常启动 ipython
    instance = None
    def __call__(self, *args, **kwargs):
    if self.instance is None:
    from IPython.core import ultratb
    self.instance = ultratb.FormattedTB(mode='Plain', color_scheme='Linux', call_pdb=1)
    return self.instance(*args, **kwargs)
    ```
    XIVN1987
        7
    XIVN1987  
       2021-02-08 10:33:21 +08:00
    python 解释器交互太简陋了,,建议用 ipdb 进入 ipython

    import ipdb; ipdb.set_trace() # 设置断点

    class ExceptionHook: # 异常启动 ipython
    &nbsp ;&nbsp ; instance = None
    &nbsp ;&nbsp ; def __call__(self, *args, **kwargs):
    &nbsp ;&nbsp ;&nbsp ;&nbsp ; if self.instance is None:
    &nbsp ;&nbsp ;&nbsp ;&nbsp ;&nbsp ;&nbsp ; from IPython.core import ultratb
    &nbsp ;&nbsp ;&nbsp ;&nbsp ;&nbsp ;&nbsp ; self.instance = ultratb.FormattedTB(mode='Plain', color_scheme='Linux', call_pdb=1)
    &nbsp ;&nbsp ;&nbsp ;&nbsp ; return self.instance(*args, **kwargs)
    XIVN1987
        8
    XIVN1987  
       2021-02-08 10:34:32 +08:00
    python 解释器交互太简陋了,,建议用 ipdb 进入 ipython

    import ipdb; ipdb.set_trace() # 设置断点

    class ExceptionHook: # 异常启动 ipython
    ....instance = None
    ....def __call__(self, *args, **kwargs):
    ........if self.instance is None:
    ............from IPython.core import ultratb
    ............self.instance = ultratb.FormattedTB(mode='Plain', color_scheme='Linux', call_pdb=1)
    ........return self.instance(*args, **kwargs)
    XIVN1987
        9
    XIVN1987  
       2021-02-08 10:35:05 +08:00
    @no1xsyzy

    大佬,,你回复里的代码缩进怎么弄的??
    no1xsyzy
        10
    no1xsyzy  
       2021-02-08 11:34:38 +08:00   ❤️ 2
    @XIVN1987 全角空格(
    XIVN1987
        11
    XIVN1987  
       2021-02-08 11:47:51 +08:00   ❤️ 1
    全角空格,试一下:

    class ExceptionHook: # 异常启动 ipython
       instance = None
       def __call__(self, *args, **kwargs):
         if self.instance is None:
           from IPython.core import ultratb
           self.instance = ultratb.FormattedTB(mode='Plain', color_scheme='Linux', call_pdb=1)
         return self.instance(*args, **kwargs)
    XIVN1987
        12
    XIVN1987  
       2021-02-08 11:48:22 +08:00   ❤️ 1
    @no1xsyzy

    哇塞,,真的行了,,感谢大佬
    byaiu
        13
    byaiu  
       2021-02-08 12:17:47 +08:00
    @XIVN1987 笑喷了
    no1xsyzy
        14
    no1xsyzy  
       2021-02-08 12:24:18 +08:00
    @XIVN1987 这个 ExceptionHook 是要实例化了以后放到 sys.excepthook 吗?

    既然你提到了我所不知道的,那我就多嘴一句,hacker 大多偏左推崇人人平等从而不喜欢 “大佬” 这种叫法。
    learningman
        15
    learningman  
       2021-02-08 12:26:12 +08:00 via Android
    @no1xsyzy 但是算法竞赛的圈子流行这个
    人均大佬神犇 (
    XIVN1987
        16
    XIVN1987  
       2021-02-08 12:36:55 +08:00
    @no1xsyzy

    是的,,抱歉拷贝不完整

    class ExceptionHook:      # 异常启动 ipython
       instance = None
       def __call__(self, *args, **kwargs):
         if self.instance is None:
           from IPython.core import ultratb
           self.instance = ultratb.FormattedTB(mode='Plain', color_scheme='Linux', call_pdb=1)
         return self.instance(*args, **kwargs)

    sys.excepthook = ExceptionHook()
    XIVN1987
        17
    XIVN1987  
       2021-02-08 12:42:22 +08:00
    @byaiu

    实在是 V2EX 回复中插入空格方式太奇葩了,,我都注册六年了今天才学会,,
    loliordie
        18
    loliordie  
       2021-02-09 00:58:23 +08:00
    @XIVN1987 可以用 markdown 的插入代码语法吧

    ```python
    print("hello world")
    ```
    试一下
    loliordie
        19
    loliordie  
       2021-02-09 00:58:52 +08:00
    @loliordie 好吧回复居然不支持 markdown 语法...
    littleMaple
        20
    littleMaple  
    OP
       2021-02-10 16:48:17 +08:00
    @no1xsyzy #1 感谢答复,试了一下,确实有用!看来是我没有细看 pdb 模块的文档的锅.
    littleMaple
        21
    littleMaple  
    OP
       2021-02-10 16:50:26 +08:00
    @ungrown #2 自己平时调试用的话确实不必太强迫完美,但是因为可能存在未来的第三方代码使用者,所以还是遵循最小惊讶原则较好,避免接口行为的不一致.
    littleMaple
        22
    littleMaple  
    OP
       2021-02-10 16:58:54 +08:00
    @shniubobo #3 感谢答复!原来内置函数和对象的源代码是在名为 bltinmodule.c 的文件中,难怪我找不到,原来名字用了缩写,下次我会记住了!不过如果 CPython 的文档有个接口与源代码位置的对应索引表格就好了,每次要找某对象或函数的源码都需要在迷宫中自行摸索一番,StackOverflow 上面也有不少询问某个 Cpython 对象或函数的源代码具体在哪里的相关问题,这方面看来文档还有可以再改进的空间,让对 CPython 代码库不熟悉的 beginner 也能便利地 navigate.
    littleMaple
        23
    littleMaple  
    OP
       2021-02-10 17:06:55 +08:00
    @XIVN1987 #11 感谢推荐,试了一下,确实比内置的 pdb 要丰富和强化很多,虽然启动的时候略重了点,不过用起来蛮舒服的.
    littleMaple
        24
    littleMaple  
    OP
       2021-02-10 17:29:08 +08:00
    @no1xsyzy #14 @learningman #15 可能还要考量一下算法竞赛圈的大占比组成族群——初中生与高中生。至少在我所在的区域,初中生高中生中互称“大佬”,“大神”,“学霸”,“卖弱”,“我是蒟蒻”的整套言语框架算是蔚然成风的。无独有偶,名为「李借之」的 matters.news 用户也写了一篇文章 [我如何看待“大佬”这类说法 —— 对身边大陆学生口头话语的观察与思考]( https://matters.news/@lijiezhi/%E6%88%91%E5%A6%82%E4%BD%95%E7%9C%8B%E5%BE%85-%E5%A4%A7%E4%BD%AC-%E8%BF%99%E7%B1%BB%E8%AF%B4%E6%B3%95-%E5%AF%B9%E8%BA%AB%E8%BE%B9%E5%A4%A7%E9%99%86%E5%AD%A6%E7%94%9F%E5%8F%A3%E5%A4%B4%E8%AF%9D%E8%AF%AD%E7%9A%84%E8%A7%82%E5%AF%9F%E4%B8%8E%E6%80%9D%E8%80%83-zdpuB32wqJftvbH1HwNRewKnyaLxY8kPiSJVrzk9NyPyUUTmn ) 来对这一现象进行详细的观察分析,她在其文章的评论区也与持有其他观点的人进行了讨论,「竞赛圈是这个言语框架的发源地」的观点也在评论区中有出现.
    learningman
        25
    learningman  
       2021-02-10 19:09:30 +08:00
    @littleMaple 我觉得这篇文章有过度解读的嫌疑,而且作者字里行间有点偏向西方的日常来贬斥中国,不算很舒服
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5384 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 07:36 · PVG 15:36 · LAX 23:36 · JFK 02:36
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.