avatarSenior Brogrammer

Summary

The web content discusses an approach to managing configuration files in Python projects using a Singleton class pattern to ensure a single instance of the configuration is used throughout the application, optimizing performance and reducing complexity.

Abstract

The author shares their experience with handling configuration files in Python, noting the multitude of methods available and the complexity they can introduce, especially when dealing with credentials. To address this, the author explores the use of a Singleton class pattern, which guarantees that only one instance of the configuration class is created and reused, thus avoiding multiple reads of the configuration file. The implementation provided is a simplified example that demonstrates the concept of using the Singleton pattern for configuration management, which can be particularly useful in object-oriented projects. The article concludes by acknowledging the simplicity and efficiency of this approach while also acknowledging potential drawbacks.

Opinions

  • The author finds the Singleton pattern to be a useful tool for managing configurations, as it avoids the pitfalls of global variables and repeated file reads.
  • There is a recognition that while the Singleton pattern optimizes class instances and reduces the need for multiple file reads, it can be difficult to track and test due to its non-idempotent nature.
  • The author suggests that this method could be a valuable addition to the various strategies for configuration management in Python projects, particularly for those with an object-oriented design.
  • The article implies that the Singleton pattern, despite its drawbacks, offers a cleaner alternative to the traditional handling of configuration files, which can be cumbersome and error-prone.

Python Singleton Class with Configurations

This is a concept I came across recently and attempted to integrate into one of my projects with configurations. The issues I’ve ran into configuration files to this day, is there is a million ways to handle them and I just created another.

Configuration | Credit: Pete Linforth on Pixabay

Introduction

I have a configuration file that is difficult to keep from being a global variable to see or opening several times per module. The alternative could be to keep a file of Python constants that switch based on environment.

So the configuration file could potentially look like this:

# config.py
MY_CONFIG_1 = "my-sick-config-1"
MY_CONFIG-2 = "my-sick-config-2"
...

The only tricky part of this setup is handling credentials which may require an API call (or copying a version of the file locally into the environment one).

My Idea

So I came across a reading about Python singletons and decided what is the harm in using this to a configuration file. I’d have a single instance of the class that would be generated and could re-use it each time, where I would only open the file once.

I started at a couple articles and Stack Overflow answers, but ended up at the Python documentation that had an example showcase of a singleton implementation. I ended up using this for starters and worked my way through the simple setup.

Note: The example I do below is a significantly simpler setup than what I have, however it should demonstrate what I am trying to do.

So using the Python implementation of singleton I came up with the following idea:

# singleton.py
class Singleton(object):
    def __new__(cls, *args, **kwds):
        it = cls.__dict__.get("__it__")
        if it is not None:
            return it
        cls.__it__ = it = object.__new__(cls)
        it.init(*args, **kwds)
        return it
# config.py
class Config(Singleton):
    def init(self):
        self.configurations = self._read('config.yaml')
    
    def _read(self, filename):
        with open(filename) as stream:
            return yaml.safe_load(stream)
conf1 = Config()
conf2 = Config()
assert conf1 == conf2

So now we have one instance and one read on the configuration file for each instantiation. This is nice as we can create this per module without having to worry about any performance implications of opening the file multiple times.

Pros and Cons

The setup does optimize the class as we have a single instance, but has several drawbacks in general.

Pros:

  • Reduces need for several reads
  • Replacement for global variables

Cons:

  • Difficult to track as the state never changes, but can be overused very easily
  • Difficult to test as the calls to the function aren’t idempotent

Conclusion

This is another idea to the ever increasing mess of ways to handle configurations for a project. I’d check this out if you setup the configurations easily and have a more object oriented approach to a project.

Thanks for the read.

Software Development
Python
Object Oriented
Design Patterns
Configuration Management
Recommended from ReadMedium
avatarAbhay Kumar
OOPs in Python

An easy guide

10 min read