PySnooper
GitHub上刚开源的一个项目,用来寻找 python 代码中的错误。由于平时写的代码行数量少,个人不太喜欢用那种庞大(不轻量)的调试工具,像 pycharm 之类的。以前习惯于用 print 函数打印变量查看状态来找错误。如今这个工具完美适用于我这样的人。个人认为,这个工具非常适合持续服务或者大数据集任务。
这个工具使用起来很简单,首先直接可以使用 pip 安装
pip install pysnooper
使用时,只需要在每个函数前面添加装饰器即可,比如下面的代码是 Sklearn 和 Tensorflow 机器学习实用指南(hands-on-ml-with-sklearn-and-tensorflow)里面第一章的一个数据处理函数
@pysnooper.snoop('file.log', prefix='prepare_country_stats_debug: ') def prepare_country_stats(oecd_bli, gdp_per_capita): oecd_bli = oecd_bli[oecd_bli["INEQUALITY"]=="TOT"] oecd_bli = oecd_bli.pivot(index="Country", columns="Indicator", values="Value") gdp_per_capita.rename(columns={"2015": "GDP per capita"}, inplace=True) gdp_per_capita.set_index("Country", inplace=True) full_country_stats = pd.merge(left=oecd_bli, right=gdp_per_capita, left_index=True, right_index=True) full_country_stats.sort_values(by="GDP per capita", inplace=True) remove_indices = [0, 1, 6, 8, 33, 34, 35] keep_indices = list(set(range(36)) - set(remove_indices)) return full_country_stats[["GDP per capita", 'Life satisfaction']].iloc[keep_indices]
函数返回日志输出到 file.log 文件中了,其内容如下,prepare_country_stats_debug 是为了便于辨识一个名字。可以看出,函数变量的值以及变化都会展示出来。
prepare_country_stats_debug: Starting var:.. oecd_bli = LOCATION Country INDICATOR ... Value Flag Codes Flags 0 AUS ... prepare_country_stats_debug: Starting var:.. gdp_per_capita = Country ... Estimates Start After 0 ... prepare_country_stats_debug: 08:58:25.811795 call 9 @pysnooper.snoop('file.log', prefix='prepare_country_stats_debug: ') prepare_country_stats_debug: 08:58:25.877757 line 11 oecd_bli = oecd_bli[oecd_bli["INEQUALITY"]=="TOT"] prepare_country_stats_debug: 08:58:25.951715 line 12 oecd_bli = oecd_bli.pivot(index="Country", columns="Indicator", values="Value") prepare_country_stats_debug: Modified var:.. oecd_bli = Indicator Air pollution Assault rate ... Water quality Years in education Country ... prepare_country_stats_debug: 08:58:26.045661 line 13 gdp_per_capita.rename(columns={"2015": "GDP per capita"}, inplace=True) prepare_country_stats_debug: 08:58:26.123617 line 14 gdp_per_capita.set_index("Country", inplace=True) prepare_country_stats_debug: Modified var:.. gdp_per_capita = Subject Descri... prepare_country_stats_debug: 08:58:26.204192 line 15 full_country_stats = pd.merge(left=oecd_bli, right=gdp_per_capita, prepare_country_stats_debug: 08:58:26.281148 line 16 left_index=True, right_index=True) prepare_country_stats_debug: New var:....... full_country_stats = Air pollution Assault rate ... GDP per capita Estimates Start After Country ... prepare_country_stats_debug: 08:58:26.428064 line 17 full_country_stats.sort_values(by="GDP per capita", inplace=True) prepare_country_stats_debug: 08:58:26.574980 line 18 remove_indices = [0, 1, 6, 8, 33, 34, 35] prepare_country_stats_debug: New var:....... remove_indices = [0, 1, 6, 8, 33, 34, 35] prepare_country_stats_debug: 08:58:26.716899 line 19 keep_indices = list(set(range(36)) - set(remove_indices)) prepare_country_stats_debug: New var:....... keep_indices = [2, 3, 4, 5, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29... prepare_country_stats_debug: 08:58:26.863815 line 20 return full_country_stats[["GDP per capita", 'Life satisfaction']].iloc[keep_indices] prepare_country_stats_debug: 08:58:27.011381 return 20 return full_country_stats[["GDP per capita", 'Life satisfaction']].iloc[keep_indices]
PySnooper 参数
如上面的示例,完全可以将日志输出到一个文件中,便于查看
@pysnooper.snoop('/my/log/file.log')
也可以查看非本地变量
@pysnooper.snoop(variables=('foo.bar', 'self.whatever'))
显示函数中调用函数的snoop行
@pysnooper.snoop(depth=2)
给调试的行加个前缀名便于辨识和定位
@pysnooper.snoop(prefix='prepare_country_stats_debug: ')