Reputation: 399
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
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