If you use Parameter.__getstate__() and .__setstate__() (which are there so pickle can work), it might even be easier:
where the 'state' for each Parameter is (self.name, self.value, self.vary, self.expr, self.min, self.max, self.stderr, self.correl, self.init_value)
I would suggest having save() and restore() be methods of the Parameters class.
Should the "save()" method take a file handle or file name, or even just return the json string and let the user save it however? I might opt for the last option (because I might want to dump those to HDF5 or an sqlite database rather than to a textfile), or perhaps take an *optional* filename *and* return the string too.
Likewise, should restore() take a file handle, file name, or string? Not sure.
If you use Parameter.__getstate__() and .__setstate__() (which are there so pickle can work), it might even be easier:where the 'state' for each Parameter is (self.name, self.value, self.vary, self.expr, self.min, self.max, self.stderr, self.correl, self.init_value)Is there a reason why __getstate__ and __setstate__ return tuples and not dict?
def __getstate__(self):
"""get state for pickle"""
return {'name': self.name, 'value': self.value, 'vary', self.vary, 'expr': self.expr, 'min': self.min,
'max': self.max, 'stderr': self.stderr, 'correl': self.correl, 'init_value': self.init_value}I would suggest having save() and restore() be methods of the Parameters class.For restore to be a method it would have to pop all the parameters first:map(pars.pop, pars.keys())Before adding them back in again.
Should the "save()" method take a file handle or file name, or even just return the json string and let the user save it however? I might opt for the last option (because I might want to dump those to HDF5 or an sqlite database rather than to a textfile), or perhaps take an *optional* filename *and* return the string too.Likewise, should restore() take a file handle, file name, or string? Not sure.
My preference is for save and restore to take a file handle. Then calling code can deal with all the problems of setting a file up. The file handle doesn't have to be a file, it could be a file-like, e.g. stringIO object. save could return the string.
state = one_param.__getstate__()this_param = Parameter()this_param.__setstate__(state)so the contents of 'state' is not as crucial as being internally consistent.
I agree that for human editing, the json dump of this Parameter state is worse than an INI file section. Again, it's a question of what the intention is.
Yeah, I guess that a restore() method is a little trickier than the save() method, as the saved state may not have the same set of parameters as the current parameter list. So, it's not completely clear whether "restore" means "make the union of" or "completely replace, deleting if necessary". I think either is fine, as long as it is clearly documented.
Should the "save()" method take a file handle or file name, or even just return the json string and let the user save it however? I might opt for the last option (because I might want to dump those to HDF5 or an sqlite database rather than to a textfile), or perhaps take an *optional* filename *and* return the string too.Likewise, should restore() take a file handle, file name, or string? Not sure.
My preference is for save and restore to take a file handle. Then calling code can deal with all the problems of setting a file up. The file handle doesn't have to be a file, it could be a file-like, e.g. stringIO object. save could return the string.Sure. The alternative would be to just deal with strings and have the user handling I/O however they choose (including SQL, HDF5, or sent over a wire). It's a small amount of data, so I would probably have used strings, but I do not have a strong preference. I guess the main question is: what is the likely usage for save()/restore()? If it's a GUI saving state or a long-running app saving multiple "parameter sets", maybe 1 string per fit result is better than 1 file per fit result.
state = one_param.__getstate__()this_param = Parameter()this_param.__setstate__(state)so the contents of 'state' is not as crucial as being internally consistent.The consistency is important. The only reason I commented on that is because it's more usual to return dict from __getstate__. dicts are futureproof, in that they don't mind if you change the ordering or add new values.
I agree that for human editing, the json dump of this Parameter state is worse than an INI file section. Again, it's a question of what the intention is.What I'd like to do in my program is save Parameters for a fit, for future reference. For example, you might be writing a paper and want to retrieve the values. pickling is fine for storage, but you have to start Python or your program up to get to the values. A large proportion of my intended user base would have problems doing that. A text file is reasonably easy to access, one just has to have Notepad (cringe)/vi/etc. I want to be able to start an editor and easily figure out what the fitted value was for a given parameter.
Using json has the advantage that it's short and easy to construct the information string. However, it's not very readable. With your json example you got a list of lists:[["x", 3, true, null, 0, Infinity, null, null, 3], ["y", 9, true, null, 2, Infinity, null, null, 9],
["z", null, true, "x*sqrt(y)", -Infinity, Infinity, null, null, null]]
The second step of a 'save', could be to flatten it. i.e. write:"x", 3, true, null, 0, Infinity, null, null, 3"y", 9, true, null, 2, Infinity, null, null, 9
"z", null, true, "x*sqrt(y)", -Infinity, Infinity, null, null, null
On reading back in, reconstitute to the list of lists so that you can reconstitute to the state required for each parameter. It is a little more code, but I think it's worth it because it is more readable to write each parameter to a separate line, and we don't need the extra square brackets.
Yeah, I guess that a restore() method is a little trickier than the save() method, as the saved state may not have the same set of parameters as the current parameter list. So, it's not completely clear whether "restore" means "make the union of" or "completely replace, deleting if necessary". I think either is fine, as long as it is clearly documented.My overwhelming choice here is to completely replace, deleting if necessary. If you have the union of something you're not reconstructing what you originally had. This is why in my original code I wrote a restore function returning a Parameters instance rather than a method.
Should the "save()" method take a file handle or file name, or even just return the json string and let the user save it however? I might opt for the last option (because I might want to dump those to HDF5 or an sqlite database rather than to a textfile), or perhaps take an *optional* filename *and* return the string too.Likewise, should restore() take a file handle, file name, or string? Not sure.
My preference is for save and restore to take a file handle. Then calling code can deal with all the problems of setting a file up. The file handle doesn't have to be a file, it could be a file-like, e.g. stringIO object. save could return the string.Sure. The alternative would be to just deal with strings and have the user handling I/O however they choose (including SQL, HDF5, or sent over a wire). It's a small amount of data, so I would probably have used strings, but I do not have a strong preference. I guess the main question is: what is the likely usage for save()/restore()? If it's a GUI saving state or a long-running app saving multiple "parameter sets", maybe 1 string per fit result is better than 1 file per fit result.
The json/pickle module have dump and dumps. The first is write to file, the second is write to string. Perhaps we could have save/saves, or just use dump/dumps as the names, the first writing to file, the second writing to string.When my GUI saves state it is pickling, when my user saves a parameter set I want to save text for the reasons outlined above.