Search code examples
pythonpython-3.xclass-method

Calling subsclass @classmethod from parent class


I'm trying to do the following:

class A:

    @classmethod
    def test_function(cls, message):
      cls.__get_the_function()

class B(A):

    @classmethod
    def __get_the_function(cls):
        return print("BBBB")


class C(A):

    @classmethod
    def __get_the_function(cls):
        return print("CCCC")

however when I call:

B.test_function("Test")

I get the following:

AttributeError: type object 'B' has no attribute '_A__get_the_function'

I want class A to __get_the_function from the subclass (either class B or C depends on which one I use), but it looks like it is trying to look for it in itself.

NOTE: I'm using Python 3.8.2


Solution

  • __-prefixed names are handled specially during class creation. The name is replaced when the function is defined by a mangled name, as if you had defined the function as

    @classmethod
    def test_function(cls, message):
        cls._A__get_the_function()
    

    in the first place.

    This is done to explicitly provide a way to hide a name from a subclass. Since you want to override the name, __get_the_function isn't an appropriate name; use an ordinary _-prefixed name if you want to mark it as private:

    class A:
    
        @classmethod
        def test_function(cls, message):
          cls._get_the_function()
    
        # Define *something*, since test_function assumes it
        # will exist. It doesn't have to *do* anything, though,
        # until you override it.
        @classmethod
        def _get_the_function(cls):
            pass