I have a class which constructor is getting overly complicated so I wanted to use a builder pattern to manage all the construction steps.
The thing is an important part of the application depends on the old way of instantiating the class, so I can't just replace them all in one go. I have used a decorator to mark some methods as deprecated, but I'd like to throw a warning if the class is being instantiated outside of the builder class.
To give a little more context, the constructor of the original class (Inverter
) looks like this:
def __init__(self, inverter_id: str, location: Tuple[str, str], plant_id: str,
customer_id: str, power_threshold: float = 0, resolution: int = 5,
**kwargs):
"""
Creates a new inverter object.
:param inverter_id:
unique identifier of the inverter.
"""
# metrics initialization
self._customer_id = customer_id
self._plant_id = plant_id
self._expected_power = DataFrame()
self._generated_power = DataFrame()
self._total_pr = 0.0
self._specific_performance = 0.0
self._active_pr = 0.0
self._generated_energy = 0.0
self._expected_energy = 0.0
self.__operational_time = {}
self.__off_time = {}
self.__savings = 0.0
# parameters initialization
self._power_threshold = power_threshold
self._resolution = 5
self._energy_rate = kwargs['energy_rate']
self._lines = []
# identification
self._id = inverter_id
self._location = location
self._resolution = resolution
# data storing
self._inverter_electric_data = None
self._inverter_environmental_data = None
self._inverter_metadata = None
And many of the parameters are then feeded to the class by other methods, and the idea would be to feed those values to the builder class like:
inverter = InverterBuilder().set_id("some_id").build()
My initial idea was to add a deprecation warning to the constructor but that would make the builder throw the warning too.
So, is there a way to throw a warning when the original class constructor is called from outside of the builder class?
For example, throw a warning if someone does:
inverter = Inverter(...)
As an additional note, I'm using the deprecation
library to mark the methods as deprecated.
Your original __init__
already takes a **kwargs
argument - use it.
...
def __init__(self, inverter_id: str, location: Tuple[str, str], plant_id: str,
customer_id: str, power_threshold: float = 0, resolution: int = 5,
**kwargs):
"""
Creates a new inverter object.
:param inverter_id:
unique identifier of the inverter.
"""
...
if kwargs.get('invokewarning',True):
#issue warning
Then the builder can pass invokewarning=False
.
I imagine there are a few other ways to solve this.