How can you extend a python property?
A subclass can extend a super class\'s function by calling it in the overloaded version, a
You should be calling the superclass properties, not bypassing them via self._dataframe
. Here's a generic example:
class A(object):
def __init__(self):
self.__prop = None
@property
def prop(self):
return self.__prop
@prop.setter
def prop(self, value):
self.__prop = value
class B(A):
def __init__(self):
super(B, self).__init__()
@property
def prop(self):
value = A.prop.fget(self)
value['extra'] = 'stuff'
return value
@prop.setter
def prop(self, value):
A.prop.fset(self, value)
And using it:
b = B()
b.prop = dict((('a', 1), ('b', 2)))
print(b.prop)
Outputs:
{'a': 1, 'b': 2, 'extra': 'stuff'}
I would generally recommend placing side-effects in setters instead of getters, like this:
class A(object):
def __init__(self):
self.__prop = None
@property
def prop(self):
return self.__prop
@prop.setter
def prop(self, value):
self.__prop = value
class B(A):
def __init__(self):
super(B, self).__init__()
@property
def prop(self):
return A.prop.fget(self)
@prop.setter
def prop(self, value):
value['extra'] = 'stuff'
A.prop.fset(self, value)
Having costly operations within a getter is also generally to be avoided (such as your parse method).
If I understand correctly what you want to do is call the parent's method from the child instance. The usual way to do that is by using the super
built-in.
I've taken your tongue-in-cheek example and modified it to use super
in order to show you:
class NormalMath(object):
def __init__(self, number):
self.number = number
def add_pi(self):
n = self.number
return n + 3.1415
class NewMath(NormalMath):
def add_pi(self):
# this will call NormalMath's add_pi with
normal_maths_pi_plus_num = super(NewMath, self).add_pi()
return int(normal_maths_pi_plus_num)
In your Log example, instead of calling:
self._dataframe = LogFile.dataframe.getter()
you should call:
self._dataframe = super(SensorLog, self).dataframe
You can read more about super here
Edit: Even thought the example I gave you deals with methods, to do the same with @properties shouldn't be a problem.
You have some possibilities to consider:
1/ Inherit from logfile
and override parse
in your derived sensor class. It should be possible to modify your methods that work on dataframe
to work regardless of the number of members that dataframe
has - as you are using pandas a lot of it is done for you.
2/ Make sensor
an instance of logfile
then provide its own parse method.
3/ Generalise parse
, and possibly some of your other methods, to use a list of data descriptors and possibly a dictionary of methods/rules either set in your class initialiser or set by a methods.
4/ Look at either making more use of the methods already in pandas, or possibly, extending pandas to provide the missing methods if you and others think that they would be accepted into pandas as useful extensions.
Personally I think that you would find the benefits of options 3 or 4 to be the most powerful.
The problem is that you're missing a self going into the parent class. If your parent is a singleton then a @staticmethod should work.
class X():
x=1
@staticmethod
def getx():
return X.x
class Y(X):
y=2
def getyx(self):
return X.getx()+self.y
wx = Y()
wx.getyx()
3