Scripted objects saving attributes

Introduction
Scripted objects are rebuilt every time a FCStd document is opened. To do this the document keeps a reference to the module and Python class that were used to create the object, along with its properties.

Attributes of the class used to create the object can also be saved, that is, "serialized". This can be further controlled by the and  methods of the class.

Saving all attributes
By default, attributes saved in an object class are those from the dictionary of the class.

An object can be created using this class, and it can be saved to. If no particular viewprovider is assigned to the new object, its proxy class is simply set to a value different from, in this case, to.

When we re-open the file we can inspect the dictionary of the object's class.

We see that all attributes that start with in the class were saved. These can be of different types, including string, list, float, and dictionary. The original tuple for was converted to a list, but otherwise all attributes were loaded the same.

Saving specific attributes
We can define a class similar to the first one, that implements specific attributes to save.

The return value of is the object that will be serialized. This can be a single value, or a tuple of values. When the object is restored, the class calls the method, passing the  variable with the serialized content. In this case is a tuple that is unpacked into the respective variables to reconstruct the "state" that original existed.

We can create an object with this class, and save the document, just like in the previous example. When we re-open the file we can inspect the dictionary of the object's class.

The original tuple for was converted to a list, but otherwise the information was recovered fine. Instead of restoring all attributes like in the previous case, only the attributes that we specified in and  were restored.

Identifying the type
Normally, scripted objects should use properties to store information, as these are automatically restored when the document is opened.

However, sometimes the class restore internal information which is not intended to be modified, but which is helpful to inspect.

For example, most objects of the Draft Workbench set up a attribute that can be used to determine the type of object that is under use.

All objects have a property, but for scripted objects this property is not useful, as it always refers to the parent C++ class, for example, Part_Part2DObject or Part_Feature. Therefore, having this additional attribute in the class is useful to treat each object in a particular way.

Migrating the object
Version information can be stored inside the class in order to verify the origin of an object.

If the structure of the class changes, that is, if its properties or methods change, are renamed, or are removed, we could test the version attribute in order to migrate the older object to a new set of properties or to a new class. This can be done by implementing the method, as explained in Scripted objects migration.

Links

 * Scripted objects
 * Scripted objects migration
 * FreeCAD Forum Discussion: Scripted Object Serialization: json or pickle?


 * obj.Proxy.Type is a dict, not a string, explanation of and  in the forum.
 * The Pickle module in the Python documentation.