Python объекты - это контейнер, атрибуты которого вы можете установить. Если вы не устанавливаете атрибут, но пытаетесь прочитать его, вы получаете AttributeError
, что означает, что искомый атрибут не существует.
В настоящее время student = Student(...)
вызывает Student.__init__
, что назначает атрибут name
и ID
объекта. Вы никогда не вызываете student.setAge
или student.setMarks
, поэтому атрибуты age
и marks
вашего объекта никогда не устанавливаются и не могут быть доступны.
Традиционно присваивать значения по умолчанию в методе __init__
если вы хотите вообще избежать непредвиденных сбоев, подобных этому.
Другое дело, что вместо использования методов получения и установки, как Java, например, Python поощряет использование свойств. Свойства - это объекты в шаблоне класса, к которым можно обращаться как к обычному атрибуту, но они позволяют запускать произвольный код вместо операторов доступа и присваивания.
Собрав все это вместе, вы могли бы написать что-то вроде
class Student:
def __init__(self, name, ID, age=None, marks=None):
self.name = name
self.ID = ID
self.age = random.randint(0, 100) if age is None else age
self.marks = random.randint(0, 100) if marks is None else marks
@property
def marks(self):
return self._marks
@marks.setter
def marks(self, value):
# Example of a check you could do
if not isinstance(value, int):
raise TypeError('Marks must be an integer')