Python - extending properties like you'd extend a function

前提是你 提交于 2019-12-01 16:17:40

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
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!