@Iceforest

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

получается сложить один объект с другим, а если сложить с другим выходим ошибка
# Таблица преобразований:
# Вода + Воздух = Шторм
# Вода + Огонь = Пар
# Вода + Земля = Грязь
# Воздух + Огонь = Молния
# Воздух + Земля = Пыль
# Огонь + Земля = Лава

# Сложение элементов реализовывать через __add__
# Если результат не определен - то возвращать None
# Вывод элемента на консоль реализовывать через __str__
class Aqua:
    def __str__(self):
        return 'Вода'

    def __add__(self, other):
        if Fire() + Aqua():
            return Vapor(part1=self, part2=other)
        elif Aqua() + Air():
            return Storm(part1=self, part2=other)
        elif Aqua()+Earth():
            return Storm(part1=self, part2=other)


class Air:
    def __str__(self):
        return 'Воздух'

    def __add__(self, other):
        if Air() + Aqua():
            return Storm(part1=self, part2=other)
        elif Air() + Fire():
            return Lightning(part1=self, part2=other)
        elif Air() + Earth():
            return Dust(part1=self, part2=other)


class Earth:
    def __str__(self):
        return 'Земля'

    def __add__(self, other):
        if Earth() + Aqua():
            return Dirt(part1=self, part2=other)
        elif Earth() + Fire():
            return Dirt(part1=self, part2=other)
        elif Earth() + Air():
            return Lava(part1=self, part2=other)


class Fire:
    def __str__(self):
        return 'Огонь'

    def __add__(self, other):
        if Fire() + Aqua():
            return Vapor(part1=self, part2=other)
        elif Fire()+Air():
            return Dust(part1=self, part2=other)
        elif Earth() + Fire():
            return Dirt(part1=self, part2=other)


class Storm:
    def __init__(self, part1, part2):
        self.part1 = part1
        self.part2 = part2

    def __str__(self):
        return 'Шторм'

    def __add__(self, other):
        return Storm(part1=self, part2=other)


class Vapor:
    def __init__(self, part1, part2):
        self.part1 = part1
        self.part2 = part2

    def __str__(self):
        return 'Пар'


class Lightning:
    def __init__(self, part1, part2):
        self.part1 = part1
        self.part2 = part2

    def __str__(self):
        return 'Молния'


class Dust:
    def __init__(self, part1, part2):
        self.part1 = part1
        self.part2 = part2

    def __str__(self):
        return 'Пыль'


class Dirt:
    def __init__(self, part1, part2):
        self.part1 = part1
        self.part2 = part2

    def __str__(self):
        return 'Грязь'


class Lava:
    def __init__(self, part1, part2):
        self.part1 = part1
        self.part2 = part2

    def __str__(self):
        return 'Лава'


у меня выходит ошибка RecursionError: maximum recursion depth exceeded while calling a Python object
  • Вопрос задан
  • 2370 просмотров
Решения вопроса 3
@Iceforest Автор вопроса
class Fire:
    def __str__(self):
        return 'Огонь'

    def __add__(self, other):
        if isinstance(other, Aqua):
            return Vapor(part1=self, part2=other)
        elif isinstance(other, Earth):
            return Lava(part1=self, part2=other)
        elif isinstance(other, Air):
            return Lightning(part1=self, part2=other)
Ответ написан
Комментировать
adugin
@adugin Куратор тега Python
class Element:
    recipes = {
        ('Aqua', 'Air'): 'Storm',
        ('Aqua', 'Fire'): 'Steam',
        ('Aqua', 'Earth'): 'Dirt',
        ('Air', 'Fire'): 'Lightning',
        ('Air', 'Earth'): 'Dust',
        ('Fire', 'Earth'): 'Lava',
    }
    recipes.update({(b, a): c for (a, b), c in recipes.items()})
    classes = {a for a, b in recipes.keys()} | {*recipes.values()}
    
    @classmethod
    def __str__(cls):
        return cls.__name__

    def __add__(self, other):
        if isinstance(other, self.__class__):
            return self
        try:
            return eval(self.recipes[(str(self), str(other))])()
        except KeyError:
            return None

    
for cls in Element.classes:
    exec(f'class {cls}(Element): pass')

print(Air() + Aqua())
Ответ написан
Комментировать
@Art005
Не очень понимаю что и зачем вы хотите.
Но может примерно так
def __add__(self, other):
    if isinstace(other, Fire):
        return Vapor(self, other)
    if isinstace(other, Air):
        return Dirt(self, other)
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы