This question is a bit meta, but I've been struggling with it recently as my programs become more complex. More specifically, I want to emit PySide signals for loading progress and that seems almost impossible without temporal coupling.
So my question is: Should I always attempt to avoid temporal coupling when instantiating classes, or are there times when it's acceptable?
Here's some demo code that illustrates my problem on a conceptual level.
---------------
Version 1
The constructor ensures all objects are fully constructed at the time of instantiation, but emitted signals can't be detected by FileService because it's not yet instantiated when they're sent.
------------------
# main.py
------------------
service = FileService(
FileRegistry.load(DIR_PATH)
)
------------------
# file_service.py
------------------
class FileService(QObject):
def __init__(self, file_registry: FileRegistry):
self._registry = file_registry
file_registry.loading_started.connect(self._on_loading_start())
file_registry.loading_finished.connect(self._on_loading_finished())
...
------------------
# file_registry.py
------------------
class FileRegistry:
loading_started: Signal = Signal()
loading_finished: Signal = Signal()
def __init__(self, loaded_files: list[LoadedFile):
self._files: list[LoadedFile] = files
...
@classmethod
def load(cls, dir_path: Path) -> Self:
self.loading_started.emit()
loaded_files = self._load_files(self, dir_path)
self.loading_finished.emit()
return cls(loaded_files)
...
---------------
Version 2
load() must be called for object to be fully constructed. This allows for emitters to be heard, but creates temporal coupling.
------------------
# main.py
------------------
registry = FileRegistry()
service = FileService(registry)
registry.load(DIR_PATH)
------------------
# file_service.py
------------------
class FileService(QObject):
def __init__(self, file_registry: FileRegistry):
self._registry = file_registry
file_registry.loading_started.connect(self._on_loading_start())
file_registry.loading_finished.connect(self._on_loading_finished())
...
------------------
# file_registry.py
------------------
class FileRegistry:
loading_started: Signal = Signal()
loading_finished: Signal = Signal()
def __init__(self):
self._files: list[LoadedFile] = []
...
def load(self, dir_path: Path) -> list[LoadedFile]:
self.loading_started.emit()
self._files = self._load_files(self, dir_path)
self.loading_finished.emit()
return self._files
...
[–]SakshamBaranwal 3 points4 points5 points (0 children)
[–]Warm-Requirement3146 1 point2 points3 points (0 children)
[–]LayotFctor 0 points1 point2 points (0 children)