Python - extending properties like you'd extend a function

前端 未结 4 1585
甜味超标
甜味超标 2021-01-11 17:42

Question

How can you extend a python property?

A subclass can extend a super class\'s function by calling it in the overloaded version, a

相关标签:
4条回答
  • 2021-01-11 18:19

    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).

    0 讨论(0)
  • 2021-01-11 18:34

    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.

    0 讨论(0)
  • 2021-01-11 18:39

    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.

    0 讨论(0)
  • 2021-01-11 18:40

    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
    
    0 讨论(0)
提交回复
热议问题