10

I have a general debugging question in python (pycharm IDE if it matters)

Lets say I have code which is made up of 2 blocks:

Code block 1 (takes very long to run)
Code block 2 (where I want to debug)

Is there a way to save the current variables at the end of running code block 1, so that I can "rewind" back to those variables states and debug from there, without having the re-run the entire script to recompute those variables?

Lee88
  • 1,185
  • 3
  • 15
  • 27

3 Answers3

2

You can certainly "save" the current variables at the end of running code block 1. Just store the variables in a dictionary and write that to a file after the first code block finishes.

Here's a very minimal example, since you provided no data:

import csv

# code block 1
for i in range(1000000): # meant to simulate a "long" time
    var1 = 2*i
    var2 = 4*i

# basically this is a log that keeps track of the values of these variables
to_save = {'var1': var1, 'var2': var2}

# write that dictionary to a file
with open('my_log.csv', 'w+') as f:
    w = csv.DictWriter(f, to_save.keys())
    w.writeheader()
    w.writerow(to_save)

# continue with code block 2
for i in range(1000):
    var1 = "BLAH"
    var2 = "BLAH BLAH"
blacksite
  • 12,086
  • 10
  • 64
  • 109
2

I am unaware of a general solution to this problem. But an application specific solution can be constructed using various methods for serializing objects, but I would suggest pickle for this problem.

Like so much else, there is a small example already on SO.

Community
  • 1
  • 1
Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135
0

I just want to add something to the pickle response.

My general approach also includes pickle, but combined with pytest and pytest fixtures.

I wrap the code I want to debug inside a test and mock the time-consuming operations to return the value of the pre-pickled values.

Illustrative example:

@pytest.fixture
def data():
    return pickle.load(...)
    

def test(data):
    with mock.patch("heavy_func") as mocked:
        mocked.return_value = data

        # my_func makes a call to `heavy_func` but at that moment
        # `heavy_func` will be a mock object and will return `data`
        # no matter the params you provide to it.
        # Usefully also to get rid of HTTP and DB calls when 
        # testing.
        result = my_func() 

And then I debug the test

Raydel Miranda
  • 13,825
  • 3
  • 38
  • 60