Robyc
Robyc

Reputation: 399

Initialize different classes in a similar way

I have different Classes which I need to initialize partially in almost the same way. The init function takes in input a file path and/or some numpy data.

class InertialData1:
   def __init__(self, file=None, data=None):
      # --- this is the (almost) common part ---
      if file is None:
        self.file = 'Unknown path to file'
      else:
        self.file = file
      assert isinstance(self.file, str)

      if data is None:
        self.data = read_logfile(file, 'a_token')
      else:
        self.data = data
      assert isinstance(self.data, np.ndarray)
      # --- end of the common part ---

      # Here other stuff different from class to class

The token in the read_logfile() function (an external function) also changes from class to class.

class InertialData2:
   def __init__(self, file=None, data=None):
      # here the common code as above, but with 'another_token' instead of 'a_token'
      # here other stuff
...

Writing the same lines in all the classes definition is a no go, of course.

Possible solution.

I thought about defining an external function like this

def initialize(file, data, token):
    if file is None:
        file = 'Unknown path to file'
    else:
        file = file
    assert isinstance(file, str)

    if data is None:
        data = read_logfile(file, token)
    else:
        data = data
    assert isinstance(data, np.ndarray)
return file, data

Then I could use it inside the init method of each class like this:

class InertialData1:
   def __init__(self, file=None, data=None):
        self.file = file
        self.data = data
        self.file, self.data = initialize(self.file, self.data, token='a_token')

This way seems to be working. I just have the feeling it is not the best way of doing it, or not pythonic, and I hope to learn something from your answers :) Thanks

Upvotes: 0

Views: 256

Answers (1)

Feliks Montez
Feliks Montez

Reputation: 548

You should be able to DRY (Don't Repeat Yourself) up your code by using class inheritance:

class InertialData:
  def __init__(self, file=None, data=None):
    # --- this is the common part ---
    if file is None:
      self.file = 'Unknown path to file'
    else:
      self.file = file
    assert isinstance(self.file, str)

  def init_data(self, token, data):
    if data is None:
      self.data = read_logfile(self.file, token)
    else:
      self.data = data
    assert isinstance(self.data, np.ndarray)

class InertialData1(InertialData):
  def __init__(self, file=None, data=None):
    # --- this is the different part ---
    super().__init__(file=file, data=data);
    self.init_data('token_a', data)

Notice a few things:

You can make a "common" class, InertialData, that has the repeated functionality. Then All of your custom classes can inherit from the common one. See how the class InertialData1 takes InertialData as a parameter?

In all classes that inherit from InertialData, you can call super and this will call the __init__ method of the superclass, which in this case is InertialData.

The bit of code that initializes the data that has the differing token for each class has been pulled into a function that takes the token as a parameter. Now you can call initialize_data('token_a') in the __init__ function of any class that inherits from InertialData.

I renamed your classes to begin with capital letters (as is Python's convention).

Upvotes: 1

Related Questions