Search code examples
pythonconfiguration-files

How to write configuration files for a Python program which contains lots of different classes?


Currently I have a Python file that contains dozons of classes, and each class takes 5-10 parameters in its constructor function.

Every time when I want to change the default values for those parameters, I need to go through the whole file to look for those constructor functions, and modify them manually, that is not too complicated, but would be a little bit messy sometimes.

I am wondering are there any ways to write a human-readable configuration file for it such that I could directly modify some entries in this config file to change the corresponding default parameters? How should I do that?

Thanks!


Solution

  • You could write a configuration file in any format.

    Python ships ready with support for JSON, XML and a format similar to traditional sectioned config files (configparser). All these formats have support for nested structures (the last one in a slightly less useful way).

    Another option chosen by many Python projects is to write the config file in Python itself. Indeed, a Python dictionary almost looks like JSON so it should be easy to read and write even for people who don't know Python very well. The file can then be loaded and dynamically evaluated which means you can also use fancy stuff like retrieving environment variables, recursively loading other files or using handy functions like os.path.whatever. If you'd rather not execute such “untrusted” code, have a look at ast.literal_eval.

    Whatever format you chose, you should write a little config module that provides a function to retrieve a configuration value given a key. The key could be a string like module.submodule.class.parameter that is broken into parts by the function and used to look up the entry in the hierarchical structure of the config file. It will probably be best to load the configuration once into an in-memory data structure and then serve all requests from that structure. You can do the loading lazily the first time the function is called.