Home > Software design >  Python accessing parent class variable as instant variable in child class
Python accessing parent class variable as instant variable in child class

Time:04-07

I'm trying to access instance variables of a parent class as class variables in a child class.

The purpose is that the parent class will have a lot of child classes which all need to have the same structure, and a lot of different people will be working with and creating these child classes, without needing to know the inner workings of the parent class. Here's my example:

class Human(ABC):

    def __new__(cls, *args, **kwargs):
        cls.human_name = args[0]
        cls.source = f'database_{cls.__name__}'.lower()
        return super().__new__(cls)

    @property
    @abstractmethod
    def query(self):
        pass


class Company:
    class Employee(Human):
        query = f'SELECT {human_name} FROM {source};'

        # these two functions are just for testing and will not be in the final product
        def print_something(self):
            print(self.human_name)

        def print_source(self):
            print(self.source)


e = Company.Employee('John')
print(e.human_name)
print(e.query)
e.print_source()

I want to be able to create a child class of parent class Human (structured together in Company) where I only need to define the query variable which should automatically recognise the variables human_name and source.

How would I go about making this as simple as possible? Is this even possible? Many thanks!

CodePudding user response:

So, you need to actually implement the property.

class Human(ABC):

    def __new__(cls, *args, **kwargs):
        cls.human_name = args[0]
        cls.source = f'database_{cls.__name__}'.lower()
        return super().__new__(cls)

    @property
    @abstractmethod
    def query(self):
        pass


class Company:
    class Employee(Human):
        @property
        def query(self):
            return f'SELECT {self.human_name} FROM {self.source};'

        # these two functions are just for testing and will not be in the final product
        def print_something(self):
            print(self.human_name)

        def print_source(self):
            print(self.source)


e = Company.Employee('John')
print(e.human_name)
print(e.query)
e.print_source()

Note, however, since __new__ creates class variables... this query will always be the same across instances:

employee1 = Company.Employee('John')
employee2 = Company.Employee('Jack')

print(employee1.query)
print(employee2.query)

will print:

SELECT Jack FROM database_employee;
SELECT Jack FROM database_employee;
  • Related