Q:

How to refactor method returning closure to be pickleable?

My particular problem is Django related, but I rewrote the relevant code to general Python for better understanding.
import pickle

class FieldTracker(object):
    def patch_save(self, instance):
        original_save = instance.save

        def save(**kwargs):
            ret = original_save(**kwargs)

            # use properties of self, implement new stuff etc
            print 'Used patched save'

            return ret

        instance.save = save

class Model(object):
    name_field = 'joe'

    field_tracker = FieldTracker()

    def __init__(self):
        self.field_tracker.patch_save(self)

    def save(self):
        print 'Used default save'

model = Model()
model.save()  # Uses patched version of save

pickle.dumps(model)  # Fails

Model is representation of DB row. FieldTracker tracks changes to fields in Model (name_field in this case). FieldTracker needs to patch save method after Model is instantiated. Patched save is closure inside of patch_save as it uses properties from FieldTracker, calls methods from passed instance etc.
FieldTracker cannot be pickled as one if its methods contains closure. From what I tried, save cannot be moved to class level as I get TypeError: can't pickle instancemethod objects. When I tried to move patch_save to top level it produced the same exception as above code (surprise, surprise). Moving save to top level would probably mean usage of global variables, which I want to avoid (but I haven't actually tried it).
And the question is: Is it possible to refactor FieldTracker code to be pickleable or should I use different approach (like move overriden save to model mixin)?
This is real FieldTracker if anyone cares.

A:

Why bother refactoring?  I'm guessing your really interested in pickling the classes and instances as you wrote them, right?  To do this, I'd use dill, which can pickle almost anything in python. 
>>> import dill 
>>> class FieldTracker(object):
...   def patch_save(self, instance):
...     original_save = instance.save
...     def save(**kwargs):
...       ret = original_save(**kwargs)
...       print("Used patched save")
...       return ret
...     instance.save = save
... 
>>> class Model(object):
...   name_field = 'joe'
...   field_tracker = FieldTracker()
...   def __init__(self):
...     self.field_tracker.patch_save(self)
...   def save(self):
...     print("Used default save")
... 
>>> model = Model()
>>> model.save()
Used default save
Used patched save
>>> _model = dill.loads(dill.dumps(model))
>>> _model.save()
Used default save
Used patched save

Dill also has some good tools for helping you understand what is causing your pickling to fail when your code fails.

