今天给大家介绍一个python相关的调试工具 peek 。

在 Python 开发中,调试是一个常见且重要的环节。除了断点调试以外,有时候本地开发图简单,经常会直接就是通过print或者log来输出变量值进行调试。

比如这样一段代码是很常见的:

import time

def debug_example():
    # 开始时间
    start_time = time.time()
    print("开始调试...")

    # 示例变量
    a = {1, 2, 3, 4, 5}
    print("变量 a 的值:", a)  # 打印变量值

    # 模拟一些操作
    time.sleep(1)  # 暂停 1 秒

    # 打印当前时间
    current_time = time.time() - start_time
    print("当前时间:", current_time, "秒")  # 打印执行时间

    # 打印分割线
    print("-" * 30)

    # 继续其他操作
    a.remove(4)
    print("更新后的变量 a 的值:", a)  # 打印更新后的变量值

    # 打印当前时间
    current_time = time.time() - start_time
    print("当前时间:", current_time, "秒")  # 打印执行时间

    # 打印分割线
    print("-" * 30)

debug_example()

输出结果是这样的

开始调试...
变量 a 的值: {1, 2, 3, 4, 5}
当前时间: 1.0011329650878906 秒
------------------------------
更新后的变量 a 的值: {1, 2, 3, 5}
当前时间: 1.001204490661621 秒
------------------------------

如果用peek的话:

import time
from peek import p

p.configure(enabled=True,show_enter=True, show_line_number=True, show_time=True, show_delta=True, show_exit=True)

@p()
def debug_example():
    # 示例变量
    a = {1, 2, 3, 4, 5}
    p("变量 a 的值:", a)  # 打印变量值

    # 模拟一些操作
    time.sleep(1)  # 暂停 1 秒

    p()

    # 继续其他操作
    a.remove(4)
    p("更新后的变量 a 的值:", a)
    p()


debug_example()

输出结果是这样的

#7 @ 14:50:27.626882 delta=0.003 ==> called debug_example()
#10 in debug_example() @ 14:50:27.627705 delta=0.004 ==>
    '变量 a 的值:'
    a={1, 2, 3, 4, 5}
#15 in debug_example() @ 14:50:28.634658 delta=1.011
#19 in debug_example() @ 14:50:28.636275 delta=1.012 ==>
    '更新后的变量 a 的值:'
    a={1, 2, 3, 5}
#20 in debug_example() @ 14:50:28.638626 delta=1.014
#7 @ 14:50:28.638778 delta=1.015 ==> returned None from debug_example() in 1.011896 seconds

可以看到,通过 peek​ 库,可以更方便地调试和查看变量的状态,提供了更丰富的调试信息(如行号、时间等),也不需要再手动计算当前时间,执行时间,是不是很方便~

另外,在生产环境如果不需要日志输出的时候,可以在configure​里面传入enabled=False​就可以禁用掉了。

输出到日志文件

import logging
from peek import p
logging.basicConfig(level="INFO", filename='app.log', filemode='a', 
                    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
log = logging.getLogger("demo")
p.configure(output=log.info)

安装

pip install peek-python

配置项

以下是对 peek​ 库中各个配置项的详细解释:

属性

替代选项

默认值

说明

​prefix​

​pr​

​""​

输出前缀,可以用于标识输出的内容。

​output​

​o​

​"stdout"​

输出目标,可以是 "stdout"​(标准输出)或其他目标(如文件)。

​serialize​

​pprint.pformat​

用于序列化输出的函数,默认使用 pprint.pformat​ 进行格式化。

​show_line_number​

​sln​

​False​

是否显示行号。

​show_time​

​st​

​False​

是否显示时间戳。

​show_delta​

​sd​

​False​

是否显示时间差。

​show_enter​

​se​

​True​

是否在函数进入时显示信息。

​show_exit​

​sx​

​True​

是否在函数退出时显示信息。

​show_traceback​

​stb​

​False​

是否在发生异常时显示回溯信息。

​sort_dicts​

​sdi​

​False​

是否对字典进行排序输出。

​underscore_numbers​

​un​

​False​

是否将数字用下划线分隔(例如,1000 显示为 1_000)。

​enabled​

​e​

​True​

是否启用 peek​ 功能。

​line_length​

​ll​

​160​

输出行的最大长度。

​color​

​col​

​""​

输出的颜色设置。

​level​

​l​

​0​

输出的详细级别,通常用于控制输出的详细程度。

​compact​

​c​

​False​

是否以紧凑的格式输出。

​indent​

​i​

​1​

输出时的缩进级别。

​depth​

​de​

​1000000​

输出的最大深度,控制嵌套结构的输出深度。

​wrap_indent​

​wi​

​" "​

用于换行时的缩进字符串。

​separator​

​sep​

​", "​

输出值之间的分隔符。

​context_separator​

​cs​

​" ==> "​

上下文信息的分隔符。

​equals_separator​

​es​

​"="​

键值对中键和值之间的分隔符。

​values_only​

​vo​

​False​

是否只输出值而不输出键。

​value_only_for_fstrings​

​voff​

​False​

是否仅在 f-string 中输出值。

​return_none​

​rn​

​False​

是否在函数返回 None​ 时输出信息。

​enforce_line_length​

​ell​

​False​

是否强制限制输出行的长度。

​delta​

​dl​

​0​

用于计算时间差的阈值。

Limitations

It is not possible to use peek:

  • from a frozen application (e.g. packaged with PyInstaller)

  • when the underlying source code has changed during execution

peek在这两种情况下是无法正常使用的:

  • 从冻结的应用程序中使用:当你使用像 PyInstaller 这样的工具将 Python 应用程序打包成可执行文件时,生成的应用程序被称为“冻结应用程序”。在这种情况下,peek 可能无法正常工作,因为它依赖于动态加载和反射等特性,而这些特性在冻结的环境中可能受到限制。

  • 当底层源代码在执行期间发生变化:如果在程序运行时,源代码被修改(例如,使用了热重载或动态代码生成),peek 可能无法正确跟踪和显示变量的状态。这是因为 peek 依赖于在执行时获取的源代码信息,如果这些信息发生变化,peek 可能无法提供准确的调试信息。

到这,本篇已经完结,也欢迎大家在评论区留言,分享你对日常开发时候调试的一些经验和看法~

项目地址:https://github.com/salabim/peek

Snipaste_2024-12-07_11-05-00.png