Im having trouble understanding clean way to do this. I would like a function named set_delay()
that take a variety of parameters. I have 3 different "delay types" that can be set: constant, uniform, and normal. Here is what I currently have:
def set_delay_constant(delay):
continue
def set_delay_uniform(min_delay, max_delay):
continue
def set_delay_normal(mean, std_dev, timeout):
continue
The problem I have with the above is that about ~80% of the code in each function is repeated. Ideas Ive seen are:
def set_delay(delay_type, delay=None, min_delay=None, max_delay=None, mean=None, std_dev=None, timeout=None):
continue
But when I need to extend this with more delay types, I can see this getting very long and hard to read. What is the most "pythonic" way to go about this? Thank you!
CodePudding user response:
Don't use overloading. Where the problem that you're trying to solve is "about ~80% of the code in each function is repeated", the better solution is to factor out that code into its own function, call it _set_delay
for example, then call it from each of the set_delay_*
functions.
To me, overloading only makes sense where the parameters overlap, but none do in your case. For contrast, say I write range(10)
but then I realize I want to start from 1; thanks to overloading, I can simply change it to range(1, 10)
. Meanwhile, if I added an argument to your proposed set_delay
, I would get totally different behaviour.
CodePudding user response:
I would personally move to a class based structure:
from abc import ABC, abstractmethod
class Delay(ABC):
def do_delay(self):
self._prepare_delay()
#put the 80% of overlapping code here
@abstractmethod
def _prepare_delay(self):
pass
class ConstantDelay(Delay):
def __init__(self, delay):
self.delay = delay
#custom code can go here
def _prepare_delay(self)
#more custom code here
class UniformDelay(Delay):
def __init__(self, min_delay, max_delay):
self.min_delay = min_delay
self.max_delay = max_delay
#custom code goes here
def _prepare_delay(self)
#more custom code here
#etc
Then your set_delay
function would take a single argument, an instance of a Delay
subclass:
def set_delay(delay):
pass