Call subclass static methods from superclass in Python

 What I want: To define some rich static methods based on simple methods in the superclass and to implement the simple methods in every subclass. The methods are all static, so I don't want to instantiate first to use them.

Example Code:

import abc
from abc import ABC


class Direction(ABC):
    @staticmethod
    @abc.abstractmethod
    def expr() -> str:
        pass

    @staticmethod
    def turn() -> str:
        # SUBCLASS does not exist, but that's what I want
        return "turn " + SUBCLASS.expr()


class Left(Direction):
    @staticmethod
    def expr() -> str:
        return "left"


class Right(Direction):
    @staticmethod
    def expr() -> str:
        return "right"


if __name__ == "__main__":
    print(Left.turn())
    #    Want  "turn left"
    print(Right.turn())
    #    Want  "turn right"

You can achieve this by using the cls parameter to refer to the subclass inside the static method in the superclass. Here's an updated version of your code that should work:

python
import abc from abc import ABC class Direction(ABC): @staticmethod @abc.abstractmethod def expr() -> str: pass @classmethod def turn(cls) -> str: return f"turn {cls.expr()}" class Left(Direction): @staticmethod def expr() -> str: return "left" class Right(Direction): @staticmethod def expr() -> str: return "right" if __name__ == "__main__": print(Left.turn()) # Output: "turn left" print(Right.turn()) # Output: "turn right"

In the turn() method of the Direction class, we use cls.expr() to call the expr() method of the subclass. Since cls refers to the subclass that called the method, this will correctly call the expr() method of the subclass. We also changed the turn() method to a classmethod so that it can use the cls parameter.

Comments