工做中使用Pycharm做为python开发的IDE,做为专业的python集成开发环境,其功能之强大使人折服。开发过程当中Debug是必不可少的。平时常用Pycharm的remote debug功能,很是好用。可是刚开始的时候并不了解该过程的原理,只是循序渐进的配置。因而抽空了解了一下相关知识,期待可以了解其原理,从此可以在须要的时候本身独立的配置调试环境。本文将以浅显易懂的方式讲解一下相关过程。python
常见的IDE基本都具备Local Debugger功能。通常只须要简单的配置,直接加断点并使用Debug方式运行便可使用断点调试。这是对于本地调试开发而言。若是项目已经完成并上线部署到服务端,或者是本地须要在IDE以外单独配置并启动程序,那么显然不能使用本地调试。若是可以配合日志并使用断点定位分析问题,将会事半功倍。那么如何使用本地安装的Pycharm远程调试程序?服务器
若是程序部署在远端,要在本地获取程序运行状态并进行断点调试,必然须要链接到程序并进行通信。利用Pycharm进行远程调试过程当中,Pycharm充当服务器的角色。app
首先,对Pycharm Run/Debug Configures进行配置,指定Pycharm安装端的一些属性,好比Pycharm所在主机的IP地址和端口号等。spa
而后,启动Pycharm的远程调试。这时Pycharm处于监听状态,等待独立于IDE以外运行的程序的链接。命令行
其次,在远端程序刚启动时,须要根据Pycharm Debug Configures中的配置信息,链接到Pycharm。debug
最后,链接成功以后,当远程客户端运行到本地Pycharm中设置的断点处时,便会在断点处暂停程序的执行,而在本地Pycharm命中断点处可以看到远端程序当前运行的状态和调用栈等信息并进行下一步跟踪和逐步调试。3d
本地Pycharm中调试的源代码工程应和远端运行的程序源代码保持一致。Pycharm中Remote Debug Configure的配置要保证可以被远程链接。调试
因为远程客户端使用Pycharm提供的pydevd模块链接到本地的Pycharm remote Debug,二者通信连接均遵循Pycharm自定义的协议。所以咱们没必要关心Pycharm设置断点和远程客户端命中断点过程当中两端具体的实现和处理过程,只要保证咱们的Debug Configure有效便可。而后在须要的地方经过断点暂定程序,分析当前程序状态找出问题所在。日志
下面是当前的操做环境,原理和步骤都是想通的,可根据实际状况进行配置配便可。code
当前环境:
本地完成Pycharm的安装,在安装目录找到debug-eggs文件夹,里面有两个文件:
分别对应本地python解释器为python2和python3的状况。
解压pycharm-debug.egg文件,获得的文件夹pycharm-debug中包含的是remote debug相关的模块。
远程客户端即是经过该文件夹中pydevd文件的settrace方法链接到指定的debug server的。
客户端配置:
为方便起见,咱们将客户端也放置到本地。(远端的只须要将下面的localhost改成Pycharm所在端的IP便可)
工程中添加刚才解压获得的远程调试模块:
./pycharm-debug
下面还须要封装一个链接到Remote Debug Server的文件
./PycharmRemoteDebug.py
1 import sys 2 sys.path.append('./Pycharm_debug') 3 import pydevd 4
5 if __name__ != '__main__': 6 pydevd.settrace('localhost', port=23456, stdoutToServer=True, stderrToServer=True, suspend=False)
当前待调试程序:./Main.py
1 # -*- coding:utf-8 -*-
2 import PycharmRemoteDebug 3
4 class Singleton(object): 5 _INSTANCE = {} 6
7 def __init__(self, cls): 8 self.cls = cls 9
10 def __call__(self, *args, **kwargs): 11 instance = self._INSTANCE.get(self.cls, None) 12 if not instance: 13 instance = self.cls(*args, **kwargs) 14 self._INSTANCE[self.cls] = instance 15 return instance 16
17 def __getattr__(self, key): 18 return getattr(self.cls, key, None) 19
20 @Singleton 21 class MyClass(object): 22 def __init__(self): 23 self.init_attr = "init_attr"
24 def __getattr__(self, key): 25 return self.__dict__.get(key, 1212) 26
27 if __name__ == "__main__": 28 mcls1 = MyClass() 29 mcls2 = MyClass() 30 print mcls1 is mcls2
注意调试模块pycharm-debug和连接文件PycharmRemoteDebug.py能够放置到任意的路径和位置,只须要调整模块引用的路径便可。
当前工程目录:
Pycharm Remote Debug 配置:
打开Run/Debug Configures
新建配置 Add New Configuration --> Python Remote Debug
上面的名字能够本身随便命名,端口号能够随便改,只要可用便可。
上面截图绿色部分的标记也告诉了咱们客户端链接Debug Server的步骤方法,注意第三步中使用的命令就是咱们客户端配置中的PycharmRemoteDebug.py文件中的链接命令。
选择刚才新建的Debug模式 Remote_Debug,点击绿色甲壳虫Debug按钮:
Debug Console 显示以下信息,说明本地Debug Server已经开启并在监听状态:
Starting debug server at port 23456 Use the following code to connect to the debugger: import pydevd pydevd.settrace('localhost', port=23456, stdoutToServer=True, stderrToServer=True, suspend=False) Waiting for process connection...
而后在Pycharm中设置断点。
最后启动客户端(运行Main.py,并不是在IDE中,直接双击该文件或者使用命令行执行)
Pycharm中命中断点:
Watch程序当前状态以及调用栈等信息: