Как записать атрибуты каждого экземпляра в переменную класса, при этом родительский класс записывает экземпляры всех классов в одну и ту же переменную?

Я новичок в этом, поэтому не уверен, что упускаю что-то очевидное. У меня есть класс «Питание», а затем подкласс для каждой категории продуктов питания.

Я хочу иметь dict в качестве переменной в каждом классе, которая записывает атрибут из каждого экземпляра класса. В настоящее время я пытаюсь получить имя экземпляра и цену. Поэтому предпочтительно, чтобы каждый словарь внутри подкласса содержал имена и цены экземпляров этого класса, в то время как я хочу, чтобы тот же словарь в родительском классе содержал имена и цены экземпляров в каждом из подклассов.

Это возможно? Я так и предполагал, исходя из того, как я понимаю работу наследования; однако, благодаря попыткам, которые я предпринял до этого момента, мне удалось добиться только того, чтобы каждый класс, включая подклассы и родительский класс, содержал каждое имя экземпляра и цену каждого класса.

Этого я не понимаю, так как не вижу, как словарь класса Burger получает доступ к экземплярам из словаря класса Desserts.

Я очень надеюсь, что кто-нибудь сможет помочь, так как я не знаю, как решить эту проблему, если это выполнимо в классах.

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]}

Не. Сам класс не должен нести за это ответственность — такой дизайн вообще не масштабируется за пределы чрезвычайно простых программ. Это плохая привычка.

user2357112 31.07.2024 22:29
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
1
57
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Я согласен с другими людьми, что это неустойчивая практика, но я поддерживаю стремление к знаниям! Итак, давайте сделаем это.

Насколько я понимаю, вам нужен родительский класс продуктов питания с словарем, содержащим продукт и цену всех подклассов. И каждый подкласс будет иметь что-то подобное, не содержащее стоимость+продукт родительских классов.

Проблема здесь в том, что ваши подклассы не содержат собственных словарей, поэтому их конкретным данным негде жить. Если мы реализуем конструктор dict + в каждом подклассе и вызываем конструктор суперкласса, мы сможем делать то, что вы хотите:

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}")

Это производит:

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]}

Вместо этого вы можете хранить цены в словаре, индексированном по подклассу, или словаре, индексированном по продукту, и использовать метод класса для рекурсивного агрегирования цен подклассов в словарь для вывода:

class Food:
    _prices = {}

    def __init__(self, product, price):
        self._prices.setdefault(type(self), {})[product] = price

    @classmethod
    def prices(cls):
        all_prices = cls._prices.get(cls, {})
        for subclass in cls.__subclasses__():
            all_prices |= subclass.prices()
        return all_prices

class Burger(Food):
    pass

class Desserts(Food):
    pass

так что:

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_option_1 = Desserts("dessert option 1", 15)
dessert_option_2 = Desserts("dessert option 2", 20)
dessert_option_3 = Desserts("dessert option 3", 25)

print(Food.prices())
print(Burger.prices())
print(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}
{'burger option 1': 15, 'burger option 2': 20, 'burger option 3': 25}
{'dessert option 1': 15, 'dessert option 2': 20, 'dessert option 3': 25}

Демо здесь

Обратите внимание: нет необходимости включать цены в подсписки, поскольку для каждого продукта указана только одна цена.

Другие вопросы по теме