Based upon One-line Tree in Python, here is a tree-like class where struct is accesible by attributes rather than keys (much more readable IMHO):
from collections import defaultdict
class Tree(defaultdict):
def __init__(self, *va, **kva):
super(Tree, self).__init__(*va, **kva)
def __getattr__(self, key):
return self[key]
def __setattr__(self, key, value):
self[key] = value
# uncoment if you want print to show values only
#def __repr__(self):
# return str(dict(self))
def tree(**values):
return Tree(tree, **values)
Now we can instanciate and fill our tree using attributes instead keys:
config = tree()
config.users.bob.home = '/home/bob'
config.users.bob.shell = '/bin/bash'
config.users.alice.home = '/home/alice'
config.users.alice.shell = '/usr/bin/python'
Result is a nice tree structure:
import json
print json.dumps(config, indent=3)
{
"users": {
"bob": {
"home": "/home/bob",
"shell": "/bin/bash"
},
"alice": {
"home": "/home/alice",
"shell": "/usr/bin/python"
}
}
}
You can even explicitly assign tree() objects. This allows for less verbose long list of atttributes:
config.users.mallory.home = '/home/mallory'
config.users.mallory.shell = '/bin/zsh'
config.users.mallory.password = 'secret'
config.users.mallory.realname = 'Mallory Foo Bar'
config.users.mallory.uid = 1001
config.users.mallory.gid = 2001
Instead, a one-line assignment seams less verbose:
config.users.mallory = tree(home='/home/mallory', shell='/bin/zsh', password='secret', realname='Mallory Foo Bar', uid=1001, gid=2001)
print json.dumps(config, indent=3)
{
"users": {
"mallory": {
"shell": "/bin/zsh",
"uid": 1001,
"home": "/home/mallory",
"gid": 2001,
"password": "secret",
"realname": "Mallory Foo Bar"
},
"bob": {
"home": "/home/bob",
"shell": "/bin/bash"
},
"alice": {
"home": "/home/alice",
"shell": "/usr/bin/python"
}
}
}