如何为 Python 添加远程调试能力而不修改系统代码

简介: 最近写了一些关于 Python 远程调试的扯淡向博文,第一篇是「[远程调试你的 Python 代码][1]」,第二篇是「[使用 VS Code 远程调试 Python 程序][2]」。前些日子开了一个叫做「第八个手艺人」的微信公众号,本想混个原创,骗点零花钱,于是把这些文章首发在公众号上了。可惜微信始终不给我原创标记,微信文章的阅读量也上不去,我也就渐渐失去了玩公众号兴致。 后来看到耗子叔的

最近写了一些关于 Python 远程调试的扯淡向博文,第一篇是「远程调试你的 Python 代码」,第二篇是「使用 VS Code 远程调试 Python 程序」。前些日子开了一个叫做「第八个手艺人」的微信公众号,本想混个原创,骗点零花钱,于是把这些文章首发在公众号上了。可惜微信始终不给我原创标记,微信文章的阅读量也上不去,我也就渐渐失去了玩公众号兴致。

后来看到耗子叔的新博文「为什么我不在微信公众号上写文章」,想想自己写博客的初心,果然还是不要整公众号这些幺蛾子了,回到我的博客,回到我这个可以被 Google 爬取、索引,被同行轻易搜索到的博客。

我所热爱的互联网,是一个开放、共享的互联网,而不是现在这样一个个围墙越来越高的花园。

晚上看到有同行在我的博文「远程调试你的 Python 代码」下面留言,希望得知我在文末挖下的坑该如何去填。

当时我没有立刻回复,于是就有了这篇博文。下面进入正题,如何在不改动一行系统代码的情况下,实现 Python 应用的开启调试和关闭调试。这篇博文里我不会给出实现代码,因为读者知道了实现原理之后,自己动手实现一下,也许就是几十分钟的事情。需要强调的是,这里的「系统代码」,其实是「业务系统代码」的意思,也就是我们维护的应用的代码。

我们知道,要想使用 ptvsd 为 Python 服务器开启远程调试功能,需要在代码的入口处 import ptvsd,并调用 ptvsd.settrace 方法启动 debug server。具体用法见「使用 VS Code 远程调试 Python 程序」,当时我是在代码中硬编码了对 ptvsd 的调用。我们这里需要做的,就是将这种硬编码的调用,从业务代码中剥离。

先理一下需求:

  1. 在业务代码启动之前,完成对 ptvsd 的调用
  2. 对 ptvsd 的调用,不出现在业务系统的代码中

在 Python 中,是否能做到在执行一个 py 文件之前,先执行一点别的代码呢?如果可以,那么我们就能把对 ptvsd 的调用,作为这「一点别的代码」了。

答案是肯定的。与此相关的知识点是 sitecustomize.py

After these path manipulations, an attempt is made to import a module named sitecustomize, which can perform arbitrary site-specific customizations. It is typically created by a system administrator in the site-packages directory. If this import fails with an ImportError exception, it is silently ignored. If Python is started without output streams available, as with pythonw.exe on Windows (which is used by default to start IDLE), attempted output from sitecustomize is ignored. Any exception other than ImportError causes a silent and perhaps mysterious failure of the process.

上面这段文档来自 Python 标准库的 site 模块,勉强算是解释了 sitecustomize 的用途,以及加载时机。反正基本上只要知道当我们执行 python a.py 时,sitecustomize.py 的代码会在 Python 解释器启动之后,py 文件执行之前执行就好了。也正因为这样子,我们把 ptvsd 放到 sitecustomize.py 中调用之后,千万千万要注意以下几点:

  1. 不要抛异常,以免影响 py 文件的正常执行
  2. 不要输出任何内容到 stdout,以免影响程序之间的交互
  3. 在同一个环境中启动多个 Python 进程的时候,要注意 debug 端口的分配,以及端口重复时的容错和提示
  4. 其它我没想到但是会影响预期行为的点

关于 1,我们可以通过一个巨大的 try catch,把所有异常吞掉,然后输出异常信息到日志文件或者 stderr,这样子就避免了我们在 sitecustomize.py 里不小心写出的 bug 影响到目标 py 文件的执行。毕竟 debug 开启不了事小,文件执行不了事大。

关于 2,我是曾经掉到坑里的。VS Code 的 Python 插件,是调用 Python 解释器去实现智能提示功能的,早些时候我修改了 sitecustomize.py,将一些信息输出到了 stdout,导致 VS Code 的 Python 智能提示全废了,排查这个问题费了一番功夫。

关于 3,我们可能需要引入一些稍复杂的方法,需要写几十行代码。打个比方,我们要从同一个虚拟环境中启动两个服务器进程,那么我们需要为这两个进程分配不同的调试端口。一种可行的方式是使用配置,比如用 ConfigParser 解析一个 ini 文件,从 ini 中读取到为指定进程名称配置的调试端口, 以及是否开启调试等信息,然后用 psutil 或者类似的类库,获取当前进程信息,和配置信息做个比对之后,决定当前进程是否需要开启调试,调试端口号是多少。

然后我们在开发或者集成环境中部署远程调试的时候,只需要把这个万年不变的 sitecustomize.py、根据不同环境稍作修改的 ini 文件推到目标机器的虚拟环境中就好,Python 应用的代码无需为了远程调试做任何修改。

基本上就是这样子了,摊开来说也没啥稀奇的,无非就是 sitecustomize.py 这个钩子而已,希望对读者有所启发。

Happy hacking!

目录
相关文章
|
1月前
|
机器学习/深度学习 人工智能 算法
基于Python深度学习的眼疾识别系统实现~人工智能+卷积网络算法
眼疾识别系统,本系统使用Python作为主要开发语言,基于TensorFlow搭建卷积神经网络算法,并收集了4种常见的眼疾图像数据集(白内障、糖尿病性视网膜病变、青光眼和正常眼睛) 再使用通过搭建的算法模型对数据集进行训练得到一个识别精度较高的模型,然后保存为为本地h5格式文件。最后使用Django框架搭建了一个Web网页平台可视化操作界面,实现用户上传一张眼疾图片识别其名称。
130 5
基于Python深度学习的眼疾识别系统实现~人工智能+卷积网络算法
|
2月前
|
机器学习/深度学习 人工智能 算法
猫狗宠物识别系统Python+TensorFlow+人工智能+深度学习+卷积网络算法
宠物识别系统使用Python和TensorFlow搭建卷积神经网络,基于37种常见猫狗数据集训练高精度模型,并保存为h5格式。通过Django框架搭建Web平台,用户上传宠物图片即可识别其名称,提供便捷的宠物识别服务。
352 55
|
1月前
|
安全 前端开发 数据库
Python 语言结合 Flask 框架来实现一个基础的代购商品管理、用户下单等功能的简易系统
这是一个使用 Python 和 Flask 框架实现的简易代购系统示例,涵盖商品管理、用户注册登录、订单创建及查看等功能。通过 SQLAlchemy 进行数据库操作,支持添加商品、展示详情、库存管理等。用户可注册登录并下单,系统会检查库存并记录订单。此代码仅为参考,实际应用需进一步完善,如增强安全性、集成支付接口、优化界面等。
|
5天前
|
机器学习/深度学习 人工智能 算法
基于Python深度学习的【蘑菇识别】系统~卷积神经网络+TensorFlow+图像识别+人工智能
蘑菇识别系统,本系统使用Python作为主要开发语言,基于TensorFlow搭建卷积神经网络算法,并收集了9种常见的蘑菇种类数据集【"香菇(Agaricus)", "毒鹅膏菌(Amanita)", "牛肝菌(Boletus)", "网状菌(Cortinarius)", "毒镰孢(Entoloma)", "湿孢菌(Hygrocybe)", "乳菇(Lactarius)", "红菇(Russula)", "松茸(Suillus)"】 再使用通过搭建的算法模型对数据集进行训练得到一个识别精度较高的模型,然后保存为为本地h5格式文件。最后使用Django框架搭建了一个Web网页平台可视化操作界面,
43 11
基于Python深度学习的【蘑菇识别】系统~卷积神经网络+TensorFlow+图像识别+人工智能
|
2月前
|
存储 缓存 监控
局域网屏幕监控系统中的Python数据结构与算法实现
局域网屏幕监控系统用于实时捕获和监控局域网内多台设备的屏幕内容。本文介绍了一种基于Python双端队列(Deque)实现的滑动窗口数据缓存机制,以处理连续的屏幕帧数据流。通过固定长度的窗口,高效增删数据,确保低延迟显示和存储。该算法适用于数据压缩、异常检测等场景,保证系统在高负载下稳定运行。 本文转载自:https://www.vipshare.com
132 66
|
22天前
|
存储 缓存 Java
Python高性能编程:五种核心优化技术的原理与Python代码
Python在高性能应用场景中常因执行速度不及C、C++等编译型语言而受质疑,但通过合理利用标准库的优化特性,如`__slots__`机制、列表推导式、`@lru_cache`装饰器和生成器等,可以显著提升代码效率。本文详细介绍了这些实用的性能优化技术,帮助开发者在不牺牲代码质量的前提下提高程序性能。实验数据表明,这些优化方法能在内存使用和计算效率方面带来显著改进,适用于大规模数据处理、递归计算等场景。
58 5
Python高性能编程:五种核心优化技术的原理与Python代码
|
2月前
|
Python
课程设计项目之基于Python实现围棋游戏代码
游戏进去默认为九路玩法,当然也可以选择十三路或是十九路玩法 使用pycharam打开项目,pip安装模块并引用,然后运行即可, 代码每行都有详细的注释,可以做课程设计或者毕业设计项目参考
78 33
|
1月前
|
机器学习/深度学习 算法 前端开发
基于Python深度学习果蔬识别系统实现
本项目基于Python和TensorFlow,使用ResNet卷积神经网络模型,对12种常见果蔬(如土豆、苹果等)的图像数据集进行训练,构建了一个高精度的果蔬识别系统。系统通过Django框架搭建Web端可视化界面,用户可上传图片并自动识别果蔬种类。该项目旨在提高农业生产效率,广泛应用于食品安全、智能农业等领域。CNN凭借其强大的特征提取能力,在图像分类任务中表现出色,为实现高效的自动化果蔬识别提供了技术支持。
基于Python深度学习果蔬识别系统实现
|
1月前
|
Python
[oeasy]python057_如何删除print函数_dunder_builtins_系统内建模块
本文介绍了如何删除Python中的`print`函数,并探讨了系统内建模块`__builtins__`的作用。主要内容包括: 1. **回忆上次内容**:上次提到使用下划线避免命名冲突。 2. **双下划线变量**:解释了双下划线(如`__name__`、`__doc__`、`__builtins__`)是系统定义的标识符,具有特殊含义。
32 3
|
2月前
|
JavaScript API C#
【Azure Developer】Python代码调用Graph API将外部用户添加到组,结果无效,也无错误信息
根据Graph API文档,在单个请求中将多个成员添加到组时,Python代码示例中的`members@odata.bind`被错误写为`members@odata_bind`,导致用户未成功添加。
51 10

热门文章

最新文章