Sometimes the current state of a class instance needs to be saved to be restored later. Situations like:


  • The class is used to build a rig and the rigger should be able to save the current state and continue the build at a later time.

  • The class is a tool with a Qt UI and the animators should be able to make some settings and re-open the tool later and those settings are preserved / restored.

So this is the FieldStorageMixin that allows any class to save a selection of its fields to a JSON file. You just need to inherit from it.

The output as JSON was used as that comes with Python. But this could obviously be configured to save as optionVars with Maya’s environment, on a node in the open scene etc.

import json

class FieldStorageMixin(object):
    def initFieldStorage(self, fieldNames=None, filepath=None):
        ''' Not using __init__ to be able to call it independently '''
        self.fieldNames = fieldNames
        self.filepath = filepath

    def saveFields(self):
        ''' Save fieldNames variables to JSON file '''
        fieldDict = self.compileFieldListToDict()
        with open(self.filepath, 'w') as outfile:
            json.dump(fieldDict, outfile, indent=2)

    def loadFields(self):
        ''' Load fieldNames variables from JSON file '''
        with open(self.filepath, 'r') as infile:
            restoredDataDict = json.load(infile)
        self.restoreFieldListFromDict(restoredDataDict)

    def compileFieldListToDict(self):
        ''' Takes a list of fields and saves their values in a dict and returns it. '''
        fieldDict = {}
        for fieldName in self.fieldNames:
            fieldDict[fieldName] = self.__dict__.get(fieldName, None)
        return fieldDict

    def restoreFieldListFromDict(self, fieldDict):
        '''
        Stores each key:value pair in the dict as fieldName = fieldValue in the class.
        '''
        if isinstance(fieldDict, dict):
            fieldNames = fieldDict.keys()
            for fieldName in fieldNames:
                self.__dict__[fieldName] = fieldDict.get(fieldName, None)
        else:
            ValueError("Not a dictionary: '%s' " % fieldDict)

class ExampleUsage(FieldStorageMixin):
    def __init__(self, arg1, namedArg1=None):
        self.arg1 = arg1
        self.namedArg1 = namedArg1
        print "Original fields: ", self.arg1, self.namedArg1

        self.initFieldStorage(fieldNames=['arg1', 'namedArg1'], filepath='/tmp/classFieldData.json')

        # save variables to file
        self.saveFields()

        # reset variables
        self.arg1 = 'reset'
        self.namedArg1 = 'reset'
        print "Reset fields: ", self.arg1, self.namedArg1

        # restore variables from file
        self.loadFields()
        print "Restored fields: ", self.arg1, self.namedArg1

>>> ExampleUsage('arg1Value', namedArg1='namedArg1Value')
Original fields:  arg1Value namedArg1Value
Reset fields:  reset reset
Restored fields:  arg1Value namedArg1Value

If you have any questions or comments please do get in touch on Twitter

You might be interested in
Other Tutorials