Initialising a Config class

David Raymond David.Raymond at tomtom.com
Tue Apr 11 15:38:31 EDT 2023


Not sure if I'm fully understanding the question. But one option instead of making everything class attributes is to just define __getattr__ for when it doesn't find an attribute.

Won't work for every single valid section and option name (because of spaces, name overlaps, etc) but should cover most things.
For example, you could use a dunder to separate section and option. Then something like this?


import configparser

class Config:
    def __init__(self, configFile):
        self._config = configparser.ConfigParser()
        self._config.read(configFile)
    def __getattr__(self, option):
        if "__" in option:
            section, option = option.split("__", 1)
        else:
            section = self._config.default_section
        return self._config[section][option]

c = Config("SomeConfigFile.txt")
print(c.uids__minimum_uid) #Will check for the option "minimum_uid" in the "uids" section
print(c.minimum_uid)       #Will check the default section


Not sure if that works as you said the Config class itself should not need to be changed

> Hi,
> 
> Having solved my problem regarding setting up 'logger' such that it is
> accessible throughout my program (thanks to the help on this list), I
> now have problem related to a slightly similar issue.
> 
> My reading suggests that setting up a module with a Config class which
> can be imported by any part of the program might be a reasonable approach:
> 
> 
> import configparser
> 
> class Config:
> 
>     def __init__(self, config_file):
> 
>         config = configparser.ConfigParser()
>         config.read(config_file)
>   
> 
> However, in my config file I am using sections, so 'config' is a dict of
> dicts.  Is there any cleverer generic way of initialising the class than
> 
> 
>         self.config = config
> 
> 
> ?
> 
> This seems a bit clunky, because I'll end up with something like
> 
> 
>    import config
>    ...
>    c = config.Config(config_file)
>    uids = get_uids(int(c.config["uids"]["minimum_uid"]))
> 
> 
> rather than something like, maybe
> 
> 
>    uids = get_uids(int(c.minimum_uid))
> 
> 
> or
> 
> 
>    uids = get_uids(int(c.uids_minimum_uid))
> 
> 
> So the question is: How can I map a dict of dicts onto class attributes
> in a generic way such that only code which wants to use a new
> configuration parameter needs to be changed and not the Config class
> itself?  Or should I be doing this differently?
> 
> Note that the values from ConfigParser are all strings, so I am fine
> with the attributes being strings - I'll just convert them as needed at
> the point of use (but maybe there is also a better way of handling that
> within a class).
>  
> Cheers,
> 
> Loris
>


More information about the Python-list mailing list