2

I wish to use Python code for config files. These config files are exec(ed). So basically the idea is to define configuaration like this:

section_1 = {
    "username": "peter",
    "password": "paul"
}

Side note: this is not a discussion about the pros/cons of Python code as configuration files. I like existing discussion and especially Matteo's comment. So this is not about Python as config files.

I want to "misuse" Python for configuration if you like. And I like and need the hierarchical data structure.

What I wish to offer to developers/operators managing the config is to be able to have the option to use the dot notation in key/value assignment.

So my question is: Is it possible (and if YES, then HOW) to implement the following feature?

x.y.z = 1
f.g.h.i.j = {"a": b}

Variables x and f are not defined. I would be totally happy to provide a global object (say g) in the config like this:

from app.config.directive import g

g.x.y.z = 1
g.f.g.h.i.j = {"a": b}

Is it possible to implement this with Python? Objective is to access the defined data structure with something like this:

g["x"]["y"]["z"] == 1
isinstance(g["f"]["g"]["h"]["i"]["j"], dict) == True

I do know that this is a bad idea from Python perspective. This is certainly not pythonic. Please remember: I wish to use Python for config management and basically "extend" Python with some special directives.

I hope you see what I mean. Thanks in advance.

M.Rau
  • 764
  • 5
  • 10
  • Possible duplicate of [How to use a dot "." to access members of dictionary?](https://stackoverflow.com/questions/2352181/how-to-use-a-dot-to-access-members-of-dictionary) – bison Aug 08 '18 at 20:23
  • Not really since this as about variable assignment not dict access – M.Rau Aug 08 '18 at 20:29
  • ah ok. I think I might know a way, one sec – bison Aug 08 '18 at 20:30
  • Something like this might be relevant (searched for recursive defaultdict): https://stackoverflow.com/questions/5369723/multi-level-defaultdict-with-variable-depth – c2huc2hu Aug 08 '18 at 20:50

1 Answers1

2

ok, ok this is ugly but let me know if it works for you! Took me a bit of thinking! Updated, fixed issues with indexing.

class dot(object):
"""dot.notation god class"""
    def __init__(self):
        self.next=None
    def __getitem__(self, key):
        return self.__dict__[key]
    def __setattr__(self, name, value):
        self.__dict__[name] = value
    def __getattr__(self, attr):
        if attr not in self.__dict__:
            self.__dict__[attr] = dot()
        return self.__dict__[attr]

>>> x=dot()
>>> x.g.h.j=3
>>> x['g']
<__main__.dot object at 0x1023f6cd0>
>>> x['g']['h']['j']
3

So... It will recessively create and instance of itself via the set dunder method. Each x in x.x.x.x.y will be of type dot and y will be the only thing with a value.

bison
  • 739
  • 5
  • 21
  • you made my day. Was guessing this is something around setattr and getattr but could not get it working! Thanks – M.Rau Aug 08 '18 at 21:10
  • You will have to play with this a bit to make each attr accessible via `g["x"]["y"]["z"]` I hit recursion depth if I try to access an element that isn't at the end. If I have time after work I can come back and try to fix it. Glad to help! really having fun learning the language by trying to help with overflow questions – bison Aug 08 '18 at 21:10
  • @M.Rau Fixed it for you, productivity at work is low – bison Aug 08 '18 at 21:34