Source code for pymodaq_utils.factory

# -*- coding: utf-8 -*-
"""
Created the 04/11/2022

@author: Sebastien Weber
"""
from typing import Callable, Union
from abc import ABCMeta, abstractmethod

from pymodaq_utils.logger import set_logger, get_module_name

logger = set_logger(get_module_name(__file__))


[docs] class BuilderBase(ABCMeta): """Abstract class defining an object/service builder with a callable interface accepting some arguments See https://realpython.com/factory-method-python/ for some details See Also -------- pymodaq.post_treatment.process_1d_to_scalar """ @abstractmethod def __call__(self, *args, **kwargs): pass
[docs] class ObjectFactory(metaclass=ABCMeta): """Generic ObjectFactory with a decorator register to add object builders to the factory with a unique key identifier See https://realpython.com/factory-method-python/ for some details Examples -------- @ObjectFactory.register('custom') def my_custom_builder(): pass See Also -------- pymodaq.post_treatment.process_1d_to_scalar.Data1DProcessorFactory """ _builders = {}
[docs] @classmethod def register(cls, key: str) -> Callable: def inner_wrapper(wrapped_class: Union[BuilderBase, Callable]) -> Callable: if cls.__name__ not in cls._builders: cls._builders[cls.__name__] = {} if key not in cls._builders[cls.__name__]: cls._builders[cls.__name__][key] = wrapped_class else: logger.warning(f'The {cls.__name__}/{key} builder is already registered. Replacing it') return wrapped_class return inner_wrapper
@property def builders(self): return self._builders
[docs] def keys_function(self, do_sort=True): if do_sort: return self.keys else: return list(self.builders[self.__class__.__name__].keys())
@property def keys(self): return sorted(list(self.builders[self.__class__.__name__].keys()))
[docs] @classmethod def create(cls, key, **kwargs): builder = cls._builders[cls.__name__].get(key) if not builder: raise ValueError(key) return builder(**kwargs)
[docs] @classmethod def get_class(cls, key): return cls._builders[cls.__name__].get(key)