Reputation: 987
I'm trying to understand inheritance in Python. I have 4 different kind of logs that I want to process: cpu, ram, net and disk usage
I decided to implement this with classes, as they're formally the same except for the log file reading and the data type for the data. I have a the following code (log object is a logging object instance of a custom logging class)
class LogFile():
def __init__(self,log_file):
self._log_file=log_file
self.validate_log()
def validate_log(self):
try:
with open(self._log_file) as dummy_log_file:
pass
except IOError as e:
log.log_error(str(e[0])+' '+e[1]+' for log file '+self._log_file)
class Data(LogFile):
def __init__(self,log_file):
LogFile.__init__(self, log_file)
self._data=''
def get_data(self):
return self._data
def set_data(self,data):
self._data=data
def validate_data(self):
if self._data == '':
log.log_debug("Empty data list")
class DataCPU(Data):
def read_log(self):
self.validate_log()
reading and writing to LIST stuff
return LIST
class DataRAM(Data):
def read_log(self):
self.validate_log()
reading and writing to LIST stuff
return LIST
class DataNET(Data):
Now I want my DataNET
class to be a object of the Data
Class with some more attributes, in particular a dictionary for every one of the interfaces. How can I override the __init__()
method to be the same as the Data.__init__()
but adding self.dict={}
without copying the Data builder? This is, without explicitly specifing the DataNet
objects do have a ._data
attribute, but inherited from Data
.
Upvotes: 1
Views: 159
Reputation: 11315
Use new style classes (inherit from object) - change definition of LogFile
to:
class LogFile(object):
and init method of Data
to:
def __init__(self, log_file):
super(Data, self).__init__(log_file)
self._data = ''
Then you can define DataNET
as:
class DataNET(Data):
def __init__(self, log_file):
super(DataNET, self).__init__(log_file)
self.dict = {}
Upvotes: 2
Reputation: 1124208
Just call the Data.__init__()
method from DataNET.__init__()
, then set self._data = {}
:
class DataNET(Data):
def __init__(self, logfile):
Data.__init__(self, logfile)
self._data = {}
Now whatever Data.__init__()
does to self
happens first, leaving your DataNET
initializer to add new attributes or override attributes set by the parent initializer.
In Python 3 classes are already new-style, but if this is Python 2, I'd add object
as a base class to LogFile()
to make it new-style too:
class LogFile(object):
after which you can use super()
to automatically look up the parent __init__
method to call; this has the advantage that in a more complex cooperative inheritance scheme the right methods are invoked in the right order:
class Data(LogFile):
def __init__(self,log_file):
super(Data, self).__init__(log_file)
self._data = ''
class DataNET(Data):
def __init__(self, logfile):
super(DataNET, self).__init__(logfile)
self._data = {}
super()
provides you with bound methods, so you don't need to pass in self
as an argument to __init__
in that case. In Python 3, you can omit the arguments to super()
altogether:
class Data(LogFile):
def __init__(self,log_file):
super().__init__(log_file)
self._data = ''
class DataNET(Data):
def __init__(self, logfile):
super().__init__(logfile)
self._data = {}
Upvotes: 3