Пример 1. Атрибут класса общий для всех объектов
У всех книг одна и та же библиотека, поэтому library_name хранится в классе.
class Book:
library_name: str = "Central Library"
def __init__(self, title: str, author: str) -> None:
self.title = title
self.author = author
book1 = Book("1984", "George Orwell")
book2 = Book("Brave New World", "Aldous Huxley")
print(Book.library_name)
print(book1.library_name)
print(book2.library_name)
Что происходит: атрибут library_name принадлежит классу Book. Оба объекта читают его из класса, потому что у самих объектов такого поля нет.
Пример 2. Изменение атрибута класса через класс
Если переименовать библиотеку через Book.library_name, изменение увидят все экземпляры.
class Book:
library_name: str = "Central Library"
def __init__(self, title: str, author: str) -> None:
self.title = title
self.author = author
book1 = Book("1984", "George Orwell")
book2 = Book("Brave New World", "Aldous Huxley")
Book.library_name = "City Library"
print(book1.library_name) # City Library
print(book2.library_name) # City Library
Пример 3. Присваивание через объект создаёт собственный атрибут
Это самый частый источник путаницы. Запись через объект не меняет класс, а добавляет поле в конкретный экземпляр.
class Book:
library_name: str = "Central Library"
def __init__(self, title: str, author: str) -> None:
self.title = title
self.author = author
book1 = Book("1984", "George Orwell")
book2 = Book("Brave New World", "Aldous Huxley")
book1.library_name = "Private Shelf"
print(book1.library_name) # Private Shelf
print(book2.library_name) # Central Library
print(Book.library_name) # Central Library
print(book1.__dict__)
print(book2.__dict__)
Пример 4. Поле объекта по умолчанию
Параметр language имеет значение по умолчанию, но его можно переопределить при создании объекта.
class Book:
def __init__(self, title: str, author: str, language: str = "English") -> None:
self.title = title
self.author = author
self.language = language
book1 = Book("1984", "George Orwell")
book2 = Book("Cien años de soledad", "Gabriel García Márquez", "Spanish")
print(book1.language) # English
print(book2.language) # Spanish
Пример 5. Классовый метод как счётчик объектов
Каждое создание книги увеличивает общий счётчик. Классовый метод show_total читает атрибут класса.
class Book:
total_books: int = 0
def __init__(self, title: str, author: str) -> None:
self.title = title
self.author = author
Book.total_books += 1
@classmethod
def show_total(cls) -> None:
print(f"Total books: {cls.total_books}")
Book.show_total() # Total books: 0
book1 = Book("1984", "George Orwell")
book2 = Book("Brave New World", "Aldous Huxley")
Book.show_total() # Total books: 2
book1.show_total() # Total books: 2
Пример 6. Альтернативный конструктор
Классовый метод удобен, когда объект нужно создать не из отдельных аргументов, а из строки.
class Book:
def __init__(self, title: str, author: str) -> None:
self.title = title
self.author = author
@classmethod
def from_string(cls, data: str) -> "Book":
title, author = data.split(" - ")
return cls(title, author)
book = Book.from_string("1984 - George Orwell")
print(book.title)
print(book.author)
Пример 7. Статический метод для валидации
Метод не использует self и cls, но логически относится к классу Book.
class Book:
def __init__(self, title: str) -> None:
self.title = title
@staticmethod
def is_title_valid(title: str) -> bool:
return isinstance(title, str) and len(title) > 0
print(Book.is_title_valid("1984")) # True
print(Book.is_title_valid("")) # False
print(Book.is_title_valid(123)) # False
Пример 8. __str__ и __repr__
Два метода отвечают за строковое представление объекта: один для пользователя, другой для разработчика.
class Book:
def __init__(self, title: str, author: str) -> None:
self.title = title
self.author = author
def __str__(self) -> str:
return f"{self.title} by {self.author}"
def __repr__(self) -> str:
return f"Book(title={self.title!r}, author={self.author!r})"
book = Book("1984", "George Orwell")
print(book) # 1984 by George Orwell
print(str(book)) # 1984 by George Orwell
print(repr(book)) # Book(title='1984', author='George Orwell')
books = [book]
print(books) # [Book(title='1984', author='George Orwell')]
Как запустить в VS Code
- Создайте папку
python-fundamentals-practice/lesson-68/. - Создайте файл
attributes.pyи скопируйте в него любой пример. - Откройте терминал в VS Code (Ctrl + `).
- Активируйте виртуальное окружение:
venv\Scripts\activate(Windows) илиsource venv/bin/activate(Mac/Linux). - Запустите:
python attributes.py