views:

281

answers:

2

I am working on my program, GarlicSim, in which a user creates a simulation, then he is able to manipulate it as he desires, and then he can save it to file.

I recently tried implementing the saving feature. The natural thing that occured to me is to pickle the Project object, which contains the entire simulation.

Problem is, the Project object also includes a module-- That is the "simulation package", which is a package/module that contains several critical objects, mostly functions, that define the simulation. I need to save them together with the simulation, but it seems that it is impossible to pickle a module, as I witnessed when I tried to pickle the Project object and an exception was raised.

What would be a good way to work around that limitation?

(I should also note that the simulation package gets imported dynamically in the program.)

A: 

If you have the original code for the simulation package modules, which I presume are dynamically generated, then I would suggest serializing that and reconstructing the modules when loaded. You would do this in the Project.__getstate__() and Project.__setstate__() methods.

Robert Kern
+2  A: 

If the project somehow has a reference to a module with stuff you need, it sounds like you might want to refactor the use of that module into a class within the module. This is often better anyway, because the use of a module for stuff smells of a big fat global. In my experience, such an application structure will only lead to trouble.

(Of course the quick way out is to save the module's dict instead of the module itself.)

djc
You mean, instead of referencing to the dynamically-imported module, to reference to a class defined inside the dynamically-imported module?
cool-RR
Yes; instantiating a class dynamically seems cleaner than importing a module dynamically.
djc
That's interesting. But I think it's a bit problematic. The way my program works is that the user chooses which simulation package to import. That is, there are pre-written simulation packages for different types of simulation (e.g. one for Newtonian physics, one for game theory...). Do you suggest I just define one class inside these pre-written packages and have all the objects be attributes of it?
cool-RR
That sounds like one way to go, but it's hard to say without knowing more about how your package fits together exactly. If you want to change the least amount of code, you could just have a single class with a well-known name (e.g. the same name in each module) in the different packages and still do the dynamic import dance.
djc
Modules aren't intended to have state. Classes are intended to have state. Saving an object saves the state of a class. That's the way it's supposed to work. You "wrap" your complex simulation in a **Facade** class that encapsulates the whole simulation and can be persisted as a "single" thing. With lots of other objects inside it.
S.Lott