❌ Ошибка 1: изменение атрибута класса через объект
class Book:
library_name = "Central Library"
def __init__(self, title):
self.title = title
book1 = Book("1984")
book2 = Book("Brave New World")
book1.library_name = "Private Shelf" # создаёт атрибут объекта!
print(book2.library_name) # Central Library — не изменилось!
Почему возникает: присваивание через объект всегда создаёт или изменяет атрибут объекта, а не класса.
✅ Исправление
Book.library_name = "City Library"
print(book1.library_name) # City Library — но у book1 остался свой атрибут!
print(book2.library_name) # City Library
Чтобы изменить значение для всех объектов, пишите через имя класса. Если ранее объект уже получил собственный атрибут, его нужно удалить через del book1.library_name, иначе он будет затенять классовый.
❌ Ошибка 2: статический метод с параметром self
class Person:
@staticmethod
def greet(self):
print("Hello!")
Person.greet() # TypeError: greet() missing 1 required positional argument: 'self'
Сообщение об ошибке: TypeError: greet() missing 1 required positional argument: 'self'
Почему возникает: статический метод не получает self автоматически. Если параметр не нужен, его не должно быть в сигнатуре.
✅ Исправление
class Person:
@staticmethod
def greet() -> None:
print("Hello!")
Person.greet()
❌ Ошибка 3: __str__ печатает вместо возврата строки
class Book:
def __init__(self, title):
self.title = title
def __str__(self):
print(f"{self.title}") # неправильно!
book = Book("1984")
print(book) # None — метод ничего не возвращает
Почему возникает: __str__ должен вернуть строку. Если использовать print, метод вернёт None, и print(book) выведет None.
✅ Исправление
class Book:
def __init__(self, title):
self.title = title
def __str__(self) -> str:
return f"{self.title}"
book = Book("1984")
print(book) # 1984
❌ Ошибка 4: изменяемый атрибут класса
class Library:
books = [] # общий список для всех объектов!
def add_book(self, title):
self.books.append(title)
lib1 = Library()
lib2 = Library()
lib1.add_book("1984")
print(lib2.books) # ['1984'] — ожидали пустой список
Почему возникает: список создаётся один раз при определении класса и разделяется между всеми экземплярами.
✅ Исправление
class Library:
def __init__(self):
self.books = [] # свой список для каждого объекта
def add_book(self, title):
self.books.append(title)
lib1 = Library()
lib2 = Library()
lib1.add_book("1984")
print(lib1.books) # ['1984']
print(lib2.books) # []
Изменяемые значения по умолчанию в __init__ тоже опасны: def __init__(self, books=[]) создаст один общий список. Используйте None и проверку внутри метода.
❌ Ошибка 5: добавление атрибутов извне
class Book:
def __init__(self, title):
self.title = title
book = Book("1984")
book.isbn = "123-456" # атрибут появился из ниоткуда
print(book.isbn) # работает, но код неочевиден
Почему возникает: такие атрибуты сложно отслеживать, они не видны при чтении класса и могут привести к опечаткам.
✅ Исправление
class Book:
def __init__(self, title, isbn):
self.title = title
self.isbn = isbn
book = Book("1984", "123-456")
print(book.isbn)
Объявляйте все поля в __init__ или в теле класса. Если нужна гибкость, используйте @dataclass или словари.