有关Python调试(IPython)
Contents
2020-07-08 更新: 增加对于flask调试的说明
其他调试工具
近来翻到一篇将Python调试方法的文章1, 其中介绍了日志, pdb
, 扩展中还介绍了
几个GUI工具.
这些工具在查找错误, 分析性能时很有用.
IPython
我也分享一款简单的小工具IPython
: 这是一款交互式的Python的Shell,
拥有了强大的提示功能, 不仅能用于调试, 也能用于开发过程中
快速识别数据结构, 模拟真实的运行上下文.
这个大而全的工具其实装起来挺烦的, pip install ipython
, 你也为他只执行了一条
语句, 但是附带的程序着实不少. 所以, 尽量和virtualenv
进行配合, 将所有的库都
放置在本地.
使用IPython
其实很简单,
1 | import IPython |
这样就能在程序执行时获取一个功能强大的交互器, 以下是一个简单的例子
1 | # hello.py |
使用见下图:
图中可以直接获取a的值, 也能像正常程序一样使用Ctrl-D
退出IPython
.
通过一条语句就可以瞥见程序执行时的真正情况, 比起那些IDE
的断点功能,
我想IPython的这种功能应该更受欢迎才对.
IPython可用的场景.
这是我平时使用IPython
进行开发和调试时的场景. 如果大家也遇到了相似的场景, 也可以
利用工具来节约时间.
开发阶段, 当你不知道某个函数的返回值, 或是对文档中的数据结构有些疑问. 那么可以使用
IPython
在固定位置调用, 从而查看函数返回的数据结构使用
try-except
, 或是某些if-else
出现了问题, 可以通过插入IPython的语句来 查看当时的输入输出情况.调试时错误时,
IPython
可以充当断点, 但是它比断点的功能更强. 甚至, 你可以试着 运行一下之后的语句, 或是毫不相关的任意合法的语句. 想想吧, 这是多么舒服的操作. 你完全不可能在任何编译型语言中做到.
有些注意点.
对于IPython
的使用, 其实还是有些地方需要注意.
用过之后删除为好. 对于像
Tornado
这样的单线程框架, 如果一不小心, 预留的IPython语句被触发, 那么整个程序就停止了. 真是GG.退出程序中的
IPython.embed()
并不意味着程序的退出, 程序会接着执行之后的语句, 感觉这更像是用GDB
的调试功能.使用
IPython
时, 最好不要在for
循环中使用, 这也是可以理解的,for
循环可以有 很多次执行, 退出一个Shell之后还有许多等待进入. 最后只能用kill
关闭程序. 这样的体验我肯定大家也不想有. 如果真的想调试一下for
循环, 为什么不试着写个break
呢?最好别在
Windows
平台上使用. 实习时, 公司的电脑是Windows7
的. 每次IPython的 启动慢的让我怀疑人生. 如果你想消磨自己宝贵的时间, 那么Windows
系统真是个不错 的选择.
uwsgi中如何使用
如果你的程序是使用uwsgi启动的, IPython.embed()
操作会立刻退出, 这里, 我提供
两种方案
uwsgi配置参数
第一个方法是允许uwsgi与stdin的交互, 具体就是在uwsgi的配置文件中增加这么一句话:
1 | honour-stdin: 1 |
或是启动时使用这个参数: uwsgi --honour-stdin -y app.yaml
使用tornado调试uwsgi应用
具体的操作可以参考: 使用Tornado调试各种Python框架的程序, 这样既不用入侵原始代码, 也能有漂亮的日志输出.
针对新版的tornado与asyncio结合使用时的问题
在tornado6.0以上的环境中, 如果直接使用IPython
会报RuntimeError: This event loop is already running
的错误.
一个可行的解决方案是在程序开头使用nest_asyncio
进行patch.
1 | import os |
具体请访问: 关于IPython在asyncio模式下使用的探讨
flask应用的简单调试
6.0以后的tornado想要使用IPython调试, 有点太过于不自由了, 我只是想在本地调试, 却还要被asyncio所困扰. 因为平时我使用flask进行开发, 使用tornado又容易遇到问题. 因此, 我重新整理了一下自己的需求. 我想要的只是tornado的漂亮日志+改动文件后自动重载+方便的IPython embed操作,
1 | # tornado 的日志的处理, 以mock的形式介入 |