Search code examples
pythonclassobjectoop

How to record attributes from each instance in a class variable, while having the parent class record instances of all classes in same variable?


I'm quite new to this so not sure if I'm missing something obvious. I've got a Food class and then subclass for each category of food.

I want to have a dict as a variable in each class that records an attribute from each instance of the class. Currently, I'm trying to get the instance name and the price. So preferably, each dict within a subclass would hold the names & prices of the instances for that class, whilst, I want the same dict in the parent class to hold the names & prices of the instances in each of the subclasses.

Is this possible? I assumed so with the way I understand inheritance to work; however, with the attempts I have made up to this point, I have only been able to get it so that each class, including the subclasses and the parent class, all contain every instance name and price from every class.

This I don't understand, as I don't see how the Burger class dict is accessing instances from the Desserts class dict.

I'm really hoping someone can assist, as I'm at a loss for how to solve this one if it is doable within the classes.

class Food:

    prices = {}

    def __init__(self, product, price):
        self.product = product
        self.price = price
        self.prices[self.product] = [self.price]
    
class Burger(Food):
   pass

class Desserts(Food):
    pass

#--->burger menu
burger_option_1 = Burger("burger option 1", 15)
burger_option_2 = Burger("burger option 2", 20)
burger_option_3 = Burger("burger option 3", 25)

#--->dessert menu
dessert_option_1 = Desserts("dessert option 1", 15)
dessert_option_2 = Desserts("dessert option 2", 20)
dessert_option_3 = Desserts("dessert option 3", 25)

print(f"Food.prices: {Food.prices}")
print(f"Burger.prices: {Burger.prices}")
print(f"Desserts.prices: {Desserts.prices}")

output:
Food.prices: {'burger option 1': [15], 'burger option 2': [20], 
'burger option 3': [25], 'dessert option 1': [15], 'dessert option 
2': [20], 'dessert option 3': [25]}
Burger.prices: {'burger option 1': [15], 'burger option 2': [20], 
'burger option 3': [25], 'dessert option 1': [15], 'dessert option 
2': [20], 'dessert option 3': [25]}
Desserts.prices: {'burger option 1': [15], 'burger option 2': 
[20], 'burger option 3': [25], 'dessert option 1': [15], 'dessert 
option 2': [20], 'dessert option 3': [25]}

Solution

  • I agree with other folks that this is an unsustainable practice, but I endorse the pursuit of knowledge! So let's do it.

    From what I understand, you want a parent food class with a dict containing the product and price of all subclasses. And each subclass would have something similar, not containing the cost+product of the parent classes.

    The issue here is that your subclasses do not contain their own dictionaries, so there isn't any place for their specific data to live. If we implement a dict + constructor in each subclass and call the superclass constructor, we can do what you want:

    class Food:
        prices = {}
        def __init__(self, product, price):
            self.product = product
            self.price = price
            self.prices[self.product] = [self.price]
        
    class Burger(Food):
       burger_prices = {}
    
       def __init__(self, product, price):
            super().__init__(product, price)
            self.product = product
            self.price = price
            self.burger_prices[self.product] = [self.price]
    
    class Dessert(Food):
       dessert_prices = {}
    
       def __init__(self, product, price):
            super().__init__(product, price)
            self.product = product
            self.price = price
            self.dessert_prices[self.product] = [self.price]
    
    #--->burger menu
    burger_option_1 = Burger("burger option 1", 15)
    burger_option_2 = Burger("burger option 2", 20)
    burger_option_3 = Burger("burger option 3", 25)
    
    #--->dessert menu
    dessert_option_1 = Dessert("dessert option 1", 15)
    dessert_option_2 = Dessert("dessert option 2", 20)
    dessert_option_3 = Dessert("dessert option 3", 25)
    
    print(f"Food.prices: {Food.prices}")
    print(f"Burger.prices: {Burger.burger_prices}")
    print(f"Dessert.prices: {Dessert.dessert_prices}")
    

    This produces:

    Food.prices: {'burger option 1': [15], 'burger option 2': [20], 'burger option 3': [25], 'dessert option 1': [15], 'dessert option 2': [20], 'dessert option 3': [25]}
    Burger.prices: {'burger option 1': [15], 'burger option 2': [20], 'burger option 3': [25]}
    Dessert.prices: {'dessert option 1': [15], 'dessert option 2': [20], 'dessert option 3': [25]}