2

I have created four classes: experiment, experiment_type1, experiment_type2 and experiment_type3

experiment is an abstract class, it cannot be instantiated. It has 2 methods, __init__(self) and run(self) where run(self) is abstract.

experiment_type1 and experiment_type2 are derived from experiment. They inherit the __init__(self) from experiment (so they share the same constructor) but they implement run(self) differently from each other.

My problem is with experiment_type3 class. It also only has the run(self) method, implemented differently from experiment_type1 and experiment_type2, but its constructor takes an additional argument. Its constructor is of the form __init__(self, parameter)

Ideally I would like experiment_type3 to be derived from experiment. But there is a constructor mismatch. What is the best way to handle this? Programming in python in this case.

Edit: This is the code for experiment and experiment_type3. As you can see it depends on self.epsilon which does not exist.

import numpy as np from abc import ABC, abstractmethod from Bandit import Bandit

class experiment(ABC):
    def __init__(self, num_iter, bandit_list): #epsilon is the chance to explore, num_iter is num of iterations, bandit_list is the list of the bandits
        self.num_iter = num_iter
        self.bandit_list = bandit_list
        self.best_bandit = np.random.choice(len(bandit_list))

    @abstractmethod
    def run(self):
        raise NotImplementedError('derived class must implement run() method!')

class eg_experiment(experiment):
    def run(self):
        for iteration in range(self.num_iter):
            bandit = np.random.choice(len(self.bandit_list))
            if(np.random.random() > self.epsilon):
                bandit = self.best_bandit
            self.bandit_list[self.best_bandit].pull()
            self.best_bandit = np.argmax([bandit.current_mean for bandit in self.bandit_list])
5
  • Possible duplicate of Python: Inherit the superclass __init__ Commented Jun 2, 2017 at 15:43
  • You should include the unabridged source with your post it's much more likely to get a good response. See stackoverflow.com/q/18006310/489590 I think it's related. Commented Jun 2, 2017 at 15:43
  • Override the constructor? Commented Jun 2, 2017 at 15:48
  • I'm not sure that's the best solution. It is possible but all I want to do is add a self.parameter = parameter. Not sure that warrants code duplication of the entire constructor Commented Jun 2, 2017 at 15:53
  • Then call the super class constructor in the overridden constructor and then set your attribute? Commented Jun 2, 2017 at 16:07

2 Answers 2

3

As the comments point out, using super() on the parent class's __init__ should give you what you want.

class A:
    def __init__(self, parameter)
        self.parameter = parameter

class B(A):
    def __init__(self, parameter, new_parameter)
        super().__init__(parameter)
        self.new_parameter = parameter

or in your case

class eg_experiment(experiment):
    def __init__(num_iter, bandit_list, epsilon):
        super().__init__(num_iter, bandit_list)  #Python3
        # super(experiment,self).__init__(num_iter, bandit_list) # Pythyon2.7
        self.epsilon = epsilon
Sign up to request clarification or add additional context in comments.

Comments

0

There's a saying: "If your class only has two methods, and one is __init__, use a function instead." Especially here, where there is no common implementation of the run method. You just have a bunch of independent functions with similar signatures.

def run_experiment_one(num_iter, bandit_list):
    ...

def run_experiment_two(num_iter, bandit_list):
    ...

def run_experiment_three(num_iter, bandit_list, epislon):
    ...

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.