Home > Software design >  Pythonic function overloading?
Pythonic function overloading?

Time:12-23

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
  • Related