Search code examples
pythonclassobjectinstantiation

Accessing the class that created another class


I am creating a package with a lot of nested classes. Imagine 2 classes: House and Roof. The House can instantiate a Roof, as well as store it, change its properties, and call its methods. But how about the reverse problem? Can the Roof object find out if it was instantiated by a House and discover anything about that parent object? My hypothetical parent House object is <parent> in this pseudo-code:

class House(object):
    def __init__(self, style:str):
        self.style = style
        self.roof = Roof()

class Roof(object):
    def __init__(self):
        self.type = None
        if <parent>:
            if <parent>.style = 'Rambler':
                self.type = 'Open Gable'
            elif <parent>.style = 'Bungalow':
                self.type = 'Hip'

h = House('Bungalow')

This is just a wild guess at how this might work, but I'm testing to see if a parent class exists, and then want to access its properties. Is this possible?

I know I can pass one parameter (the House's style) to the Roof's __init__, but the real problem I'm trying to solve involves a LOT more properties, which is what I want to avoid.

I have seen packages that solve this by having the Roof class store a property __house, which I presume is to solve this problem. I assume the House passes self to the Roof constructor, but that seems like more coding and I also wonder if it duplicates the objects stored by the program.

thanks!


Solution

  • There's some technical hacky ways the generated class could figure out who called its constructor, but that would be quite messy.

    In your class design, you could make it so that Roof gets passed a reference to House in its constuctor

    class Roof:
        def __init__(self, house):
            self.house = house
    

    However, looking at your code, I see a "code smell". You're very strongly tying the two classes together when the way a Roof's style is set depends on the type of the house.

    The "cleaner" way would be to allow a Roof to be created with whatever style the creator of the roof desires:

    class Roof:
        def __init__(self, style):
            self.style = style
    

    And then inside of House you'd pick which style of Roof goes with which style of house. That way the Roof wouldn't need a reference back to the house anyway.