I have JSON file that contains the structure of neural networks. I would like to convert the JSON file to an object, but, if possible, ignore the lists.
For example, this is the content of the JSON file:
{
"name": "model_6",
"network": {
"input_shape": [3],
"output_shape": [9, 50],
"layers": [
{"type": "Linear", "in_features": 3, "out_features": 1024},
{"type": "ReLU"},
{"type": "View", "shape": [-1, 16, 64]},
{"type": "Conv1d", "in_channels": 16, "out_channels": 32, "kernel_size": 3, "padding":0, "dilation":2},
# ...
]
}
}
And I would like to be able to access like an object, e.g. config.network.layers but having the list not converted into an object. Therefore, for example,
print(config.network.layers)
would give me :
[
{"type": "Linear", "in_features": 3, "out_features": 1024},
{"type": "ReLU"},
{"type": "View", "shape": [-1, 16, 64]},
{"type": "Conv1d", "in_channels": 16, "out_channels": 32, "kernel_size": 3, "padding":0, "dilation":2}
# ...
]
I tried using the solution using SimpleNamespace:
import json
from types import SimpleNamespace
with open('model.json') as f:
config = json.loads(f.read(), object_hook=lambda d: SimpleNamespace(**d))
But it is really not that convenient for my application because what is inside the list also get converted into object and it messes up with other parts of the code
If I understand correctly, the issue is to convert a nested dict into dot-accessible nested objects.
You can use the famous Bunch pattern to turn a dict into a dot-accessible object:
class Bunch(object):
def __init__(self, adict):
self.__dict__.update(adict)
And then use it recursively for the nested dicts:
def to_bunch(d):
if isinstance(d, dict):
return Bunch({k: to_bunch(v) for k, v in d.items()})
return d
Usage example:
d = json.loads("""
{
"name": "model_6",
"network": {
"input_shape": [3],
"output_shape": [9, 50],
"layers": [
{"type": "Linear", "in_features": 3, "out_features": 1024},
{"type": "ReLU"},
{"type": "View", "shape": [-1, 16, 64]},
{"type": "Conv1d", "in_channels": 16, "out_channels": 32, "kernel_size": 3, "padding":0, "dilation":2}
]
}
}
""")
Then:
>>> config = to_bunch(d)
... config.network.layers
[{'type': 'Linear', 'in_features': 3, 'out_features': 1024},
{'type': 'ReLU'},
{'type': 'View', 'shape': [-1, 16, 64]},
{'type': 'Conv1d',
'in_channels': 16,
'out_channels': 32,
'kernel_size': 3,
'padding': 0,
'dilation': 2}]
Bonus: in an interactive environment, you get tab-completion! (E.g. start with config. and hit <TAB>, and it will show you name and network, etc.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With