lebolo
lebolo

Reputation: 2150

How to avoid redefining default parameter with Python inheritance

For simple inheritance such as

class Base:
  def __init__(self, env: str = 'prod'):
    #...

class Derived(Base):
  def __init__(self, env: str = 'prod'):
    super().__init__(str)

How do I avoid redefining default constructor parameters in both classes? If I instantiate Derived() I do want env to default to 'prod', I just don't want to redefine the value in multiple classes. If I later decide that the default value should be something else (e.g. 'dev'), then I would have to change all derived constructors.

I was thinking of something like

class Base:
  def __init__(self, env: str = 'prod'):
    #...

class Derived(Base):
  def __init__(self, env: str = None):
    if env is None:
      super().__init__()
    else:
      super().__init__(env)

or maybe defining the default value as a global constant in the base class? Either method seems overly complex. What's the Pythonic way?

Upvotes: 5

Views: 1721

Answers (2)

6761646f6e
6761646f6e

Reputation: 91

Another option that has its pros and cons could be to use kwargs. Something like:

class Base:
  def __init__(self, env: str='prod'):
    #...

class Derived(Base):
  def __init__(self, **kwargs):
    super().__init__(**kwargs)

Upvotes: 0

Valentin B.
Valentin B.

Reputation: 622

Make a class variable.

class Base:
    DEFAULT_ENV = "prod"
    def __init__(self, env=None):
        if env is None:
            env = self.DEFAULT_ENV
        # ...

If you want to have a different default env in a subclass, just override DEFAULT_ENV in that class. If you want to change your default env for all classes that do not override it, changing DEFAULT_ENV in Base will work.

Also redifining __init__ in a subclass is optional in Python so if you don't want __init__ in your subclasses to implement different behavior from Base just ommit it in subclasses. Another advantage of having your default env in a class variable is that if you want to change only that in a subclass you can override the class variable and you do not have to redifine __init__ in the child !

EDIT: if you feel that env determination might require some funny business (like testing for environment variables, or anything else in your app) later on, you might want to wrap default_env in a property:

class Base:
    DEFAULT_ENV = "prod"
    def __init__(self, env=None):
        if env is None:
            env = self.default_env
        # ...
    @property
    def default_env(self):
        return self.DEFAULT_ENV

That way later on you can implement the expected behaviour in the property getter.

Upvotes: 2

Related Questions