pythoninheritancestatic-methods

Is this the correct use of staticmethods?


Suppose I have two classes A and B, where B inherits from A. A and B both have a bar method. A has a foo method which is inherited by B.

I now want bar from A to be called whenever foo is called, irrespective of whether an object is an instance of B or A.

I googled and found that I should probably use @staticmethod. Is something like this correct? Or is it bad programming or some kind of logic error?

class A:
    def foo(self):
        self.bar()
        A.bar_static()
        
    def bar(self):
        print('Iam A')

    @staticmethod
    def bar_static():
        print('Iam A')

class B(A):
    def bar(self):
        print('Iam B')

    @staticmethod
    def bar_static():
        print('Iam B')

Output (this is what I want):

b = B()
b.foo()

Iam B
Iam A

Edit: A possible Application is to compute a (thermodynamic) property, via a prop function. prop needs to call prop_aux to compute stuff. prop and prop_aux are implemented by both, A and B, which are different models (B is an extension of A and therefore inherits from A). Now, the B implementation of prop calls the B implementation of prop_aux. However, since it's only extending the existing A model, it also calls the A implementation of prop (via super()). To compute stuff, the A implementation of prop calls prop_aux. When this happens, the A implementation of prop shall call the A implementation of prop_aux and not the B implementation of prop_aux (which would happen the self object is of class B.


Solution

  • You could use staticmethod here. I will say, this seems like code smell in the design of your class.

    And like most applications of staticmethod, just defining and using a regular function would suffice and probably be easier to understand:

    class A:
        def foo(self):
            self.bar()
            _bar_a()
            
    def _bar_a(self):
        print('Iam A')
    
    
    class B(A):
        def bar(self):
            _bar_b()
    
        
    def _bar_b():
        print('Iam B')