0

How can I find the current base class in a classmethod invoked by super?

  • Class B inherits from A
  • The code in both data methods must be the same and should not include a literal class reference like A or B

I want the method data to gather the _data values going up the base classes.

class A:
  _data = "A data"
  @classmethod
  def data(cls) -> list[str]:
    # gather data here too, we may have N number of inheritance classes so we should try to invoke super here too

class B(A):
  _data = "B data"
  @classmethod
  def data(cls) -> list[str]:
    # gather data here and invoke super to gather data from A also

1 Answer 1

0

One can get the current base class with super().__thisclass__ Using this solution we can write the below code which meets these requirements:

  • Class B inherits from A
  • The code in both data methods must be the same and should not include a literal class reference like A or B
class A:
    _data = "A data"
    @classmethod
    def data(cls):
        super_instance = super()
        this_cls = super_instance.__thisclass__
        try:
            other_data = super_instance.data()
        except AttributeError:
            return [this_cls._data]
        return [this_cls._data] + other_data

class B(A):
    _data = "B data"
    @classmethod
    def data(cls):
        super_instance = super()
        this_cls = super_instance.__thisclass__
        try:
            other_data = super_instance.data()
        except AttributeError:
            return [this_cls._data]
        return [this_cls._data] + other_data

B.data()
# ['B data', 'A data']

Or one can refactor that into the shorter:

class DataGatherer:
    @staticmethod
    def gather_data(super_instance):
        this_cls = super_instance.__thisclass__
        try:
            other_data = super_instance.data()
        except AttributeError:
            return [this_cls._data]
        return [this_cls._data] + other_data


class A(DataGatherer):
    _data = "A data"
    @classmethod
    def data(cls):
        return cls.gather_data(super())

class B(A):
    _data = "B data"
    @classmethod
    def data(cls):
        return cls.gather_data(super())
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.