❌ Ошибка 1: изменение current_id через объект
class Student:
current_id = 1
def __init__(self, name):
self.name = name
self.student_id = Student.current_id
Student.current_id += 1
s1 = Student("Alice")
s2 = Student("Bob")
s1.current_id = 100 # создаёт атрибут объекта, класс не меняется!
s3 = Student("Carol")
print(Student.current_id) # 3
print(s1.current_id) # 100 — собственный атрибут
print(s3.student_id) # 3
Почему возникает: присваивание через объект всегда создаёт или изменяет атрибут экземпляра. Чтобы изменить счётчик для всех, нужно писать через класс.
✅ Исправление
Student.current_id = 100 # теперь значение изменилось в классе
❌ Ошибка 2: неправильный подсчёт возраста
from datetime import date
class Student:
def __init__(self, name, birth_date):
self.name = name
self.birth_date = birth_date
def calculate_age(self):
today = date.today()
return today.year - self.birth_date.year # не учитывает месяц и день!
s = Student("Alice", date(2005, 5, 10))
print(s.calculate_age()) # может быть на 1 больше до дня рождения
Почему возникает: если сегодня 1 марта, а день рождения 10 мая, разница в годах даст на один год больше, чем полных лет человеку.
✅ Исправление
def calculate_age(self):
today = date.today()
age = today.year - self.birth_date.year
if (today.month, today.day) < (self.birth_date.month, self.birth_date.day):
age -= 1
return age
❌ Ошибка 3: путаница @classmethod и @staticmethod
class Student:
def __init__(self, name, birth_date):
self.name = name
self.birth_date = birth_date
@staticmethod
def from_string(data):
name, date_string = data.split(", ")
return Student(name, date_string) # статический метод не получает cls
Почему плохо: метод привязан к конкретному имени класса Student. Если от него унаследоваться, from_string всё равно будет создавать объекты базового класса.
✅ Исправление
class Student:
@classmethod
def from_string(cls, data):
name, date_string = map(str.strip, data.split(","))
return cls(name, date_string)
❌ Ошибка 4: мутация разделяемого списка
class Student:
students = [] # общий список для всех объектов!
def __init__(self, name):
self.name = name
Student.students.append(self)
s1 = Student("Alice")
s2 = Student("Bob")
print(len(s1.students)) # 2 — ожидали, что у каждого свой список?
Почему возникает: список создаётся один раз при определении класса и разделяется между всеми экземплярами. Изменение через любой объект меняет общий список.
✅ Исправление
class Student:
def __init__(self, name):
self.name = name
students = []
students.append(Student("Alice"))
students.append(Student("Bob"))
Храните коллекции объектов снаружи класса или создавайте их в __init__, если они действительно принадлежат объекту.
Проверить по документации: подробнее об изменяемых значениях по умолчанию и правилах области видимости см. Python FAQ.