• python--debug神器pysnooper


    使用它你可以获得什么优势:

    (1)无需用print就可以获得变量的值;

    (2)以日志地形式进行保存,方便随时查看;

    (3)可以根据需要,设置调用函数的深度;

    (4)多个函数的日志,可以设置前缀进行标识;

    1.安装

    pip install pysnooper

    2.官方代码

    import pysnooper
    @pysnooper.snoop()
    def number_to_bits(number):
        if number:
            bits = []
            while number:
                number, remainder = divmod(number, 2)
                bits.insert(0, remainder)
            return bits
        else:
            return [0]
    number_to_bits(6)

    我们可以看到程序运行到哪一步, 以及到那一步时相关变量的值。

    若果你不想追踪整个函数,你可以像这样使用:

    def foo():
        lst = []
        for i in range(10):
            lst.append(random.randrange(1, 1000))
    
        with pysnooper.snoop():
            lower = min(lst)
            upper = max(lst)
            mid = (lower + upper) / 2
            print(lower, mid, upper)
    foo()

    查看一下其源代码,发现其具有以下参数:

    • output参数。该参数指定函数运行过程中产生的中间结果的保存位置,若该值为空,则将中间结果输出到控制台。
    • watch参数。该参数是vector类型, 因为在默认情况下,装饰器只跟踪局部变量,要跟踪非局部变量,则可以通过该字段来指定。默认值为空vector。
    • watch_explode参数:展开显示对象的属性或者列表/字典的值。
    • depth参数。该参数表示需要追踪的函数调用的深度。在很多时候,我们在函数中会调用其他函数,通过该参数就可以指定跟踪调用函数的深度。默认值为1。
    • prefix参数。该参数用于指定该函数接口的中间结果前缀。当多个函数都使用的该装饰器后,会将这些函数调用的中间结果保存到一个文件中,此时就可以通过前缀过滤不同函数调用的中间结果。默认值为空字符串。
    • thread_info参数,在多线程应用程序上,确定在输出中监听到哪个线程。
    • custom_repr参数,PySnooper支持装饰生成器。它将自动将修饰符应用于所有方法。(不包括属性和其他特殊情况。)
    • max_variable_length参数,默认情况下,变量和异常被截断为100个字符。
    • nomarlize参数,删除所有与机器相关的数据(路径,时间戳,内存地址),以便与其他跟踪轻松进行比较。
    其实,比较重要的就是前面几个参数。对于一般情况下也就够用了,接下来用几个小例子来看下效果。
    例子1:
    @pysnooper.snoop()
    def test(n):
        if n==1:
            return 1
        if n==2:
            return 2
        return test(n-1)+test(n-2)
    
    test(4)

    例子2:

    @pysnooper.snoop("quick_sort.txt")
    def quick_sort(a):
        if len(a)<=1:
            return a
        tmp=a[0]
        left = [i for i in a[1:] if i<=tmp]
        right = [i for i in a[1:] if i > tmp]
        return quick_sort(left)+[tmp]+quick_sort(right)
    
    quick_sort([3,5,9,4,7,2,8])

    输出比较长,就不显示全部的结果了。 

    例子3:

    class Foo(object):
        def __init__(self):
            self.num1 = 0
            self.num2 = 0
            self.sum_value = 0
    
        def add(self, num1, num2):
            return num1 + num2
        @pysnooper.snoop(output="debug.log", watch=("self.num1", "self.num2", "self.sum_value"),prefix="--foo--")
        def multiplication(self, num1, num2):
            self.num1 = num1
            self.num2 = num2
            sum_value = 0
            for i in range(0, num1):
                sum_value = self.add(sum_value, num2)
            self.sum_value = sum_value
            return sum_value
    
    foo = Foo()
    foo.multiplication(3, 4)

     注意前缀名字变了,以及全局变量的值。

  • 相关阅读:
    【C语言基础】解决C语言error: expected ‘;‘, ‘,‘ or ‘)‘ before ‘&‘ token
    【ubuntu基础】ubuntu terminal shortcut
    【CV项目调试】darknet源码中CUDNN_CONVOLUTION_FWD_SPECIFY_WORKSPACE_LIMIT问题
    【linux基础】linux 多个会话同时执行命令后history记录不全的解决方案
    【DL基础】激活函数总结
    【shell基础】判断目录是否为空
    【socketCAN错误】write: No buffer space available
    【DL基础】损失函数总结
    【CV源码实现及调试】darknet中opencv的问题
    【开源库STBI基础】STBI图像库的理解
  • 原文地址:https://www.cnblogs.com/xiximayou/p/11946503.html
Copyright © 2020-2023  润新知