I am in the process of running experiments, and ideally, once all of my code is working, the only parameters that will need to be changed will all be present in one file. My initial idea was to store these parameters in a JSON file:
{
"param1": 1,
"param2": "string parameter"
}
Where, obviously, I have many more than 2 parameters. This turns out to be a nightmare, as my IDE will not guess any of the parameters, which massively slows down my programming as I generally feel obligated to create local variables for every constant that I need in the current function that I'm working in. This results in a lot of unnecessary code (but local to that function, it is significantly more convenient than trying to index the JSON object).
My next thought was then: store the constants in a file like:
PARAM1 = 1
PARAM2 = 'string parameter'
The problem with this is that I'd like to store the parameters with experimental results so that I can look back to see which parameters were specified to produce those results.
Beyond this, my thought is to use a dataclass
(probably one with frozen=True
), as those can be converted to a dictionary. However, I do not need access to an instance of the class, just the constants within it.
Another thought is to use a class with static variables:
class ExperimentalMetaData:
param1 = 1
param2 = "string parameter"
Which can be converted to a dict
with vars(ExperimentalMetaData)
, except this will contain additional keys that should be popped off before I go about storing the data.
My question is: what is the best way to store constants in python such that they can be saved to a JSON file easily, and also be easily accessed within my code?
If you want to be able to recall different versions of inputs, give them a version
This allows you to create JSON-like input files and keep a collection of parsers which can parse them if you make a breaking change
Here's a very simple example which is more sustainable
class Parser_v1_2(): pass
class Parser_v3_2(): pass
VERSION_PARSER_MAPPING = {
"1.2": Parser_v1_2,
"3.2": Parser_v3_2,
}
def parser_map(input_file):
with open(input_file) as fh:
input_json = json.load(fh)
# get version or optionally provide a default
version = input_json.get("version", "1.0")
# dynamically select parser
return VERSION_PARSER_MAPPING[version](input_json)