加入CODE CHINA

· 不限速    · 不限空间    · 不限人数    · 私仓免费

免费加入
    README.md

    PySnooper - Never use print for debugging again

    PySnooper is a poor man's debugger. If you've used Bash, it's like set -x for Python, except it's fancier.

    Your story: You're trying to figure out why your Python code isn't doing what you think it should be doing. You'd love to use a full-fledged debugger with breakpoints and watches, but you can't be bothered to set one up right now.

    You want to know which lines are running and which aren't, and what the values of the local variables are.

    Most people would use print lines, in strategic locations, some of them showing the values of variables.

    PySnooper lets you do the same, except instead of carefully crafting the right print lines, you just add one decorator line to the function you're interested in. You'll get a play-by-play log of your function, including which lines ran and when, and exactly when local variables were changed.

    What makes PySnooper stand out from all other code intelligence tools? You can use it in your shitty, sprawling enterprise codebase without having to do any setup. Just slap the decorator on, as shown below, and redirect the output to a dedicated log file by specifying its path as the first argument.

    Example

    We're writing a function that converts a number to binary, by returning a list of bits. Let's snoop on it by adding the @pysnooper.snoop() decorator:

    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)

    The output to stderr is:

    Source path:... /my_code/foo.py
    Starting var:.. number = 6
    15:29:11.327032 call         4 def number_to_bits(number):
    15:29:11.327032 line         5     if number:
    15:29:11.327032 line         6         bits = []
    New var:....... bits = []
    15:29:11.327032 line         7         while number:
    15:29:11.327032 line         8             number, remainder = divmod(number, 2)
    New var:....... remainder = 0
    Modified var:.. number = 3
    15:29:11.327032 line         9             bits.insert(0, remainder)
    Modified var:.. bits = [0]
    15:29:11.327032 line         7         while number:
    15:29:11.327032 line         8             number, remainder = divmod(number, 2)
    Modified var:.. number = 1
    Modified var:.. remainder = 1
    15:29:11.327032 line         9             bits.insert(0, remainder)
    Modified var:.. bits = [1, 0]
    15:29:11.327032 line         7         while number:
    15:29:11.327032 line         8             number, remainder = divmod(number, 2)
    Modified var:.. number = 0
    15:29:11.327032 line         9             bits.insert(0, remainder)
    Modified var:.. bits = [1, 1, 0]
    15:29:11.327032 line         7         while number:
    15:29:11.327032 line        10         return bits
    15:29:11.327032 return      10         return bits
    Return value:.. [1, 1, 0]
    Elapsed time: 00:00:00.000001

    Or if you don't want to trace an entire function, you can wrap the relevant part in a with block:

    import pysnooper
    import random
    
    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()

    which outputs something like:

    New var:....... i = 9
    New var:....... lst = [681, 267, 74, 832, 284, 678, ...]
    09:37:35.881721 line        10         lower = min(lst)
    New var:....... lower = 74
    09:37:35.882137 line        11         upper = max(lst)
    New var:....... upper = 832
    09:37:35.882304 line        12         mid = (lower + upper) / 2
    74 453.0 832
    New var:....... mid = 453.0
    09:37:35.882486 line        13         print(lower, mid, upper)
    Elapsed time: 00:00:00.000344

    Features

    If stderr is not easily accessible for you, you can redirect the output to a file:

    @pysnooper.snoop('/my/log/file.log')

    You can also pass a stream or a callable instead, and they'll be used.

    See values of some expressions that aren't local variables:

    @pysnooper.snoop(watch=('foo.bar', 'self.x["whatever"]'))

    Show snoop lines for functions that your function calls:

    @pysnooper.snoop(depth=2)

    See Advanced Usage for more options. <------

    Installation with Pip

    The best way to install PySnooper is with Pip:

    $ pip install pysnooper

    Other installation options

    Conda with conda-forge channel:

    $ conda install -c conda-forge pysnooper

    Arch Linux:

    $ yay -S python-pysnooper

    Fedora Linux:

    $ dnf install python3-pysnooper

    License

    Copyright (c) 2019 Ram Rachum and collaborators, released under the MIT license.

    Media Coverage

    Hacker News thread and /r/Python Reddit thread (22 April 2019)

    项目简介

    🚀 Github 镜像仓库 🚀

    源项目地址

    https://github.com/cool-RR/PySnooper

    发行版本

    当前项目没有发行版本

    贡献者 28

    全部贡献者

    开发语言

    • Python 99.9 %
    • Shell 0.1 %