Python: importing settings or dependency injection
Two common approaches to configuring a python application are importing settings and dependency injection.
Importing settings involves creating a settings module or file that contains all the values and configurations needed for your application to run. These settings can then be imported into other modules and used directly. The advantage of this approach is that it is simple and easy to understand, and can work for small projects. The disadvantage is that it increases coupling to the settings module and to the way that those settings are collected. It also makes it harder to unit test a module or class without having to resort to mocking the settings module in some way.
Dependency injection involves passing dependencies (such as settings) into a class as parameters, typically using a class method that sets some class variables.
The advantage of this is that the class needs no knowledge of the settings module or how those settings are loaded. It also makes testing easier because tests can either rely on the classes default settings or inject their own test settings. The class can also be re-used more easily.
Compare these two examples:
Importing Settings
settings.py
# Some settings as class variables.. maybe use pydantic BaseSettings
class Settings():
some_setting = "some_value"
some_class.py
from settings import Settings
class SomeClass():
SOME_SETTING = Settings.some_setting
def __init__(self):
print(f"SOME_SETTING = {self.SOME_SETTING}")
Dependency Injection
settings.py
# Some settings as class variables.. maybe use pydantic BaseSettings
class Settings():
some_setting = "some_value"
# Inject the settings into the SomeClass class
from some_class import SomeClass
SomeClass.configure(some_setting=Settings.some_setting
some_class.py
class SomeClass():
SOME_SETTING = "default"
@classmethod
def configure(some_setting):
SOME_SETTING = some_setting
def __init__(self):
print(f"SOME_SETTING = {self.SOME_SETTING}")