简体   繁体   中英

How to effectively debug side effects in Python?

Is there an effective way to debug side-effects in Python?

For example, list (or any different mutable object) passed as argument to function.

>>> some_list = [1,2]
>>> some_function_with_huge_call_tree(some_list)
>>> print some_list
[2,1]

How now to determine where in the program the list has been reversed?

One more example, class instance passed as argument:

>>> print obj.x
foo
>>> some_function_with_super_huge_call_tree(obj)
>>> print obj.x
bar

Where a member of the class instance has been changed?

In both cases i want something like this:

pdb.break_on_change(some_list)  # case 1
pdb.break_on_change(obj.x)  # case 2

Unfortunately, the PDB does not have such a function.

In other words, I'm trying to find a common solution for all cases.

You could put in a mock object that tells you what is done with it.

Here is a (too) minimal example to trace down where a mutating function attribute is called.

def throw(*args, **kwargs):
    raise AssertionError()

class Mock(object):

    def __init__(self, inner):
        self.__inner = inner

    def __getattr__(self, name):
        if name == 'mutate':
            return throw
        return getattr(self.__inner, name)

Then use it as in

some_function(Mock(obj))

to find out whether some_function is mutating obj .

This example lacks many features that you would rightfully expect from a mock infrastructure. Probably worst, it doesn't support magic. Maybe you can expand it to fit your needs. Actually, I would be surprised if there wouldn't already be a library that does this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM