Is this the correct use of staticmethods?

65 Views Asked by At

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.

2

There are 2 best solutions below

0
juanpa.arrivillaga On BEST ANSWER

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')
0
KamilCuk On

now want bar from A to be called whenever foo is called

Call the function, pass the instance of the class self.

class A:
    def foo(self):
        self.bar()   # outputs I am B
        A.bar(self)  # outputs I am A
        
    def bar(self):
        print('I am A')

class B(A):
    def bar(self):
        print('I am B')
        
b = B()
b.foo()