#python #abstract-class #multiple-inheritance #abstract-methods
Вопрос:
У меня проблема с реализацией простой иерархии классов с арифметическими выражениями.
TypeError: unsupported operand type(s) for *: 'NoneType' and 'int'
и то же самое для других операций, сложения, вычитания, деления и т. Д.
Мой код:
from abc import ABC, abstractmethod class Wyrazenie(ABC): # @abstractmethod def Oblicz(self): pass class Operator(Wyrazenie): w1 = Wyrazenie() w2 = Wyrazenie() def __init__(self, wy1, wy2): self.w1 = wy1 self.w2 = wy2 #def Oblicz(self) -gt; int: # pass class Zmienna(Wyrazenie): zmienna="" slownik={} def __init__(self, klucz, wartosc): self.slownik.update({klucz: wartosc}) def Oblicz(self): return self.slownik.get(self.zmienna) class Stala(Wyrazenie): wartosc=0 def __init__(self, wartosc1): self.wartosc=wartosc1 def Oblicz(self): return self.wartosc class Dodaj(Operator): def __init__(self, wy1=None, wy2=None): super().__init__(wy1, wy2) def Oblicz(self) -gt; int: return self.w1.Oblicz() self.w2.Oblicz() class Odejmij(Operator): def __init__(self, wy1=None, wy2=None): super().__init__(wy1,wy2) def Oblicz(self) -gt; int: return self.w1.Oblicz() - self.w2.Oblicz() class Pomnoz(Operator): def __init__(self, wy1=None, wy2=None): super().__init__(wy1,wy2) def Oblicz(self) -gt; int: return self.w1.Oblicz() * self.w2.Oblicz() class Podziel(Operator): def __init__(self, wy1=None, wy2=None): super().__init__(wy1,wy2) def Oblicz(self) -gt; int: return self.w1.Oblicz() / self.w2.Oblicz() z1=Zmienna("x", 4) z2=Zmienna("y", 10) # 4 * 10 10 - 5 = 45 wyr = Dodaj(Pomnoz(z1, Stala(10)), Odejmij(z2, Stala(5))) wyr.Oblicz() print("Wartosc wyrazenia= n") print(wyr.Oblicz())
Я не знаю , является ли это проблемой с инициализацией wy1
, wy2
с None
или с совершенно неправильной идеей представления таких выражений. Я попытался переписать его из своего класса Java.
Ответ №1:
Я не уверен, почему вы добавляете так много сложностей, прежде чем исправить что-то основное, но вот что происходит:
- вы вызываете
wyr.Oblicz()
, чтоDodaj.Oblicz()
(кстати, плохая идея называть метод заглавными буквами, это очень сбивает с толку, так как он выглядит как класс) - он вызывает
self.w1.Oblicz()
перед попыткой суммировать результат с чем-то другим, и этоOblicz()
первый переданный параметрDodaj(Pomnoz(z1, Stala(10)), Odejmij(z2, Stala(5)))
, так чтоPomnoz.Oblicz()
- он вызывает
self.w1.Oblicz()
, прежде чем пытаться умножить результат на что-то другое , и это первый параметрPomnoz
, т. Е.zi
, который таковZmienna("x", 4)
Zmienna.Oblicz()
- он вызывает
self.slownik.get(self.zmienna)
, но такself.zmienna
как есть""
и нет записи для""
входаself.slownik
, он возвращаетсяNone
Это None
передается обратно, и затем умножение завершается неудачей при Pomnoz.Oblicz()
попытке выполнить его, так как оно не может умножаться None
и на целое число.
Если вы использовали IDE с отладчиком, вы могли бы отследить это самостоятельно, войдя в код, когда он вызывает дополнительные функции — подумайте об использовании чего-то вроде PyCharm, Spyder, VSCode или любого другого редактора или IDE, у которого есть средство отладки.
Ответ №2:
Я проследил ваш код и обнаружил, что причина возникновения этой ошибки в конечном счете заключается в том, что Zmienna.Oblicz
возвращается None
.
Звонок wyr.Oblicz()
такой:
wyr (Dodaj) .Oblicz -gt; wyr.w1 (Pomnoz) .Oblicz -gt; wyr.w1.w1 (z1) (Zmienna) .Oblicz -gt; self (Zmienna) .slownik.get(self.zmienna) -gt; this call returned None
В то время slownik.get
назывался, slownik
был dict
{'x': 4, 'y': 10}
содержателем и self.zmienna
был str
""
содержателем .