Home > Software engineering >  Python: Can a parent class initialiser know about child class class-attributes?
Python: Can a parent class initialiser know about child class class-attributes?

Time:02-11

Sorry if the whole python code is not good. I am still learning.

What I am trying to do is that I have a few classes which share a lot of methods. Basically, the classes only differ in some fields. When I create an object of one of these classes, I want the data used for creation to be used in an assertion to see if the created object has the expected data. The expected data is different for each class but it's the same for all objects of each class (IE it's a class attribute).

I see that the following code is marked as wrong in the IDE (""):

class OperatingSystem:
    def __init__(self, my_param):
        my_os = my_param["os"]
        assert my_os == self.os_name


class Win11(OperatingSystem):
    os_name = "Windows 11"


class Win10(OperatingSystem):
    os_name = "Windows 10"

What I think the IDE is trying to tell me by "unresolved attribute reference (os_name)" is that the parent class __init__ is called before the class variable is set. Therefore, at the time I am trying to get the class variable (init method of parent), that data is not there yet and this will certainly fail.

However, logically, the data is known already. So, there should be a way for me to make it available at ANY time. Of course, I can just put constants in the parent class or above that - but I want to give classes their own attributes and do things somewhat more OO :)

  • For example: Win11.os_name works fine even inside init of parent class...
  • Tried self.__class__.os_name - still unresolved

CodePudding user response:

You're almost there. The problem is that the base class OperatingSystem doesn't set os_name, so code like this:

os = OperatingSystem({'os': 'Windows'})

will fail when it tries to read self.os_name.

Two ways to fix this:

  1. Tell Python that OperatingSystem is an abstract base class, which means it cannot create direct instances; only its subclasses can create instances:

    from abc import ABC
    
    class OperatingSystem(ABC):
        ...
    
  2. Set os_name in the base class:

    class OperatingSystem(ABC):
        os_name = "A Generic OS"
        ...
    
  • Related