Классы
class Dog: species = "Canis familiaris" def __init__(self, name, age): self.name = name self.age = age def speak(self): return f"{self.name} says woof"rex = Dog("Rex", 3)print(rex.speak())print(rex.species)__init__— инициализатор, вызывается при создании объектаself— ссылка на текущий экземпляр, передаётся явно первым параметромspecies— атрибут класса, общий для всех экземпляров
Специальные методы
Методы с двойными подчёркиваниями определяют поведение объектов во встроенных операциях:
class Vector: def __init__(self, x, y): self.x = x self.y = y def __repr__(self): return f"Vector({self.x}, {self.y})" def __add__(self, other): return Vector(self.x + other.x, self.y + other.y) def __eq__(self, other): return self.x == other.x and self.y == other.y def __len__(self): return 2 def __bool__(self): return bool(self.x or self.y)a = Vector(1, 2)b = Vector(3, 4)print(a + b)print(a == b)Часто используемые методы: __str__, __repr__, __eq__, __lt__, __hash__, __len__, __getitem__, __iter__, __call__, __enter__, __exit__.
Наследование
class Animal: def __init__(self, name): self.name = name def speak(self): raise NotImplementedErrorclass Cat(Animal): def speak(self): return f"{self.name} says meow"class Dog(Animal): def __init__(self, name, breed): super().__init__(name) self.breed = breed def speak(self): return f"{self.name} says woof"for animal in [Cat("Tom"), Dog("Rex", "lab")]: print(animal.speak())Python поддерживает множественное наследование, порядок поиска методов определяется MRO:
print(Dog.__mro__)Инкапсуляция
В Python нет жёстких модификаторов доступа, действуют соглашения:
name— публичный атрибут_name— внутренний, не предназначен для использования снаружи__name— подвергается искажению имени (name mangling)
Свойства
class Circle: def __init__(self, radius): self._radius = radius @property def radius(self): return self._radius @radius.setter def radius(self, value): if value < 0: raise ValueError("радиус не может быть отрицательным") self._radius = value @property def area(self): return 3.14159 * self._radius ** 2c = Circle(2)c.radius = 5print(c.area)Методы класса и статические методы
class User: count = 0 def __init__(self, name): self.name = name User.count += 1 @classmethod def from_string(cls, text): name = text.split(":")[0] return cls(name) @staticmethod def is_valid_name(name): return name.isalpha()u = User.from_string("anna:25")print(User.is_valid_name("anna"))Абстрактные классы
from abc import ABC, abstractmethodclass Shape(ABC): @abstractmethod def area(self): passclass Square(Shape): def __init__(self, side): self.side = side def area(self): return self.side ** 2Создать экземпляр Shape напрямую нельзя.
dataclass
Для простых контейнеров данных:
from dataclasses import dataclass, field@dataclassclass Item: name: str price: float tags: list = field(default_factory=list)@dataclass(frozen=True, order=True)class Point: x: int y: intprint(Item("book", 10.5))print(Point(1, 2) < Point(1, 3))Декоратор автоматически создаёт __init__, __repr__, __eq__ и при необходимости методы сравнения.
__slots__
class Particle: __slots__ = ("x", "y") def __init__(self, x, y): self.x = x self.y = yИспользование __slots__ убирает словарь атрибутов у экземпляра, уменьшая расход памяти.
Задания
- Реализуйте класс
BankAccountс методами пополнения и снятия и проверкой остатка. - Создайте иерархию фигур с абстрактным методом
areaи посчитайте суммарную площадь списка фигур. - Перепишите класс точки с помощью
dataclass.
