Вызов метода в setattr - TypeError: unsupported operand type(s) for *: 'float' and 'NoneType'

karramb

Новичок
Пользователь
Июл 7, 2020
2
1
3
Приветы!
Есть задание в учебнике - найти площадь цилиндра.
Далее задача - если меняются какие-либо параметры цилиндра - необходимо автоматически пересчитать площадь цилиндра. Пытаюсь сделать это через __setattr__.
Всего 2 переменных, при проверке второй - всё ок, но при проверке первой почему-то ошибка ниже.
Помогите, пожалуйста, понять в чем ошибка)
Error
Traceback (most recent call last):
File "main.py", line 33, in <module>
a = Cylinder(1, 2)
File "main.py", line 12, in __init__
self.dia = diameter
File "main.py", line 28, in __setattr__
self.__area = self.make_area(self.dia,self.h)
File "main.py", line 8, in make_area
side = pi * d * h
TypeError: unsupported operand type(s) for *: 'float' and 'NoneType'


И вот сам код:
Python:
from math import pi


class Cylinder:

    __count=0

    @staticmethod

    def make_area(d, h):

        circle = pi * d ** 2 / 4

        side = pi * d * h

        return round(circle*2 + side, 2)


    def __init__(self, diameter, high):

        self.dia = diameter

        self.h = high

        self.__area = Cylinder.make_area(diameter, high)

    def __getattr__(self,attrname):

        if attrname=='area':

            return self.__area

        else:

            print('Error')

    def __setattr__(self, attrname, value):

        if attrname=='area':

            print('Error')

        elif attrname=='h': #Вот здесь всё ок

            self.__dict__[attrname]=value

            self.__area = self.make_area(self.dia,self.h)

        elif attrname=='dia': #Вот здесь почему-то ошибка

            self.__dict__[attrname]=value

            self.__area = self.make_area(self.dia,self.h)

        else:

            self.__dict__[attrname]=value



a = Cylinder(1, 2)

print(a.area)

print(a.make_area(1, 5))

a.h=5

print(a.area)
 
Последнее редактирование модератором:

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
Код вставляйте через кнопку ... -> код -> python.
Во время инициализации экземпляра класса (метод __init__) срабатывает метод __setattr__, который вызывает метод make_area, принимающий 2 параметра (self.dia и self.h).
Ошибка возникает потому, что на момент первого вызова метода __setattr__ (для установки значения self.dia) переменная self.h не определена и в методе make_area в строке side = pi * d * h интерпретатор не может рассчитать значение переменной side.
В тексте ошибке об этом написано (не поддерживаемые типы аргументов (float и None) для операции умножения):
Python:
TypeError: unsupported operand type(s) for *: 'float' and 'NoneType'
Исправить можно указанием начальных значений для переменных класса (self.h и self.dia):

Python:
class Cylinder:
    __count = 0
    h = 1
    dia = 1
    ...
или проверкой значения переменной h в методе make_area:
Python:
@staticmethod
def make_area(d, h):
    # h = 1 если h = None
    h = 1 if h is None else h
    circle = pi * d ** 2 / 4
    side = pi * d * h
    return round(circle * 2 + side, 2)
 
  • Мне нравится
Реакции: Student

karramb

Новичок
Пользователь
Июл 7, 2020
2
1
3
Ошибка возникает потому, что на момент первого вызова метода __setattr__ (для установки значения self.dia) переменная self.h не определена и в методе make_area в строке side = pi * d * h интерпретатор не может рассчитать значение переменной side.
В тексте ошибке об этом написано (не поддерживаемые типы аргументов (float и None) для операции умножения):
Большое спасибо, понял, что проблема в порядке задания значений переменным))
Код вставляйте через кнопку ... -> код -> python.
Отредактировал.
 
  • Мне нравится
Реакции: Student

Форум IT Специалистов