Python объекты: полное понимание сущностей

Раздел: Python -> Основы Python

Основные понятия и создание объектов

Как создать простой объект в Python с собственными атрибутами и методами?

Базовым способом является определение класса с помощью ключевого слова class и метода __init__. Через self обращаются к атрибутам конкретного экземпляра.


class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def greet(self):
        return f"Привет, меня зовут {self.name}"

p = Person("Анна", 30)
print(p.greet())
  

Python arguments types (типы аргументов в python)

Привет, меня зовут Анна
  

Python load module (загрузка модуля в python)

Пояснение: метод __init__ вызывается автоматически при создании экземпляра. Параметр self ссылается на создаваемый объект. Каждый метод экземпляра должен иметь self первым параметром.

Типичные ошибки и их решения:

  • Забытый self: если в определении метода не указать self, при вызове возникнет ошибка TypeError. Всегда добавляйте self первым параметром.
  • Изменяемые аргументы по умолчанию: def __init__(self, items=[]) создаёт один список для всех экземпляров. Используйте None и создавайте новый список внутри.
  • Попытка изменить атрибут класса через экземпляр: присваивание p.attr = value создаёт атрибут экземпляра, не изменяя класс. Для изменения атрибута класса обращайтесь к ClassName.attr.

Цель: создание полнофункциональных объектов с индивидуальными данными и поведением. Используется для большинства задач ООП.

Как быстро описать объект только с данными, без лишнего кода?

Модуль dataclasses (Python 3.7+) автоматически генерирует __init__, __repr__, __eq__ и другие методы. Достаточно объявить поля с аннотациями типов.


from dataclasses import dataclass

@dataclass
class Person:
    name: str
    age: int

p = Person("Иван", 25)
print(p)
print(p == Person("Иван", 25))
  

Pd pandas python (импорт пакетов python)

Person(name='Иван', age=25)
True
  

How to use python (как использовать python)

Аннотации указывают типы, но не проверяются во время выполнения. Для валидации можно использовать __post_init__.

Проблемы:

  • Изменяемые поля по умолчанию: если значение по умолчанию - изменяемый объект (список, словарь), Python выдаст ошибку. Используйте field(default_factory=list).
  • Наследование от dataclass: нужно правильно расставлять декораторы и учитывать порядок полей.

Цель: создание простых хранителей данных (DTO) с минимальным кодом. Удобно для конфигураций, ответов API.

Как создать неизменяемый объект с фиксированными полями?

Класс namedtuple из модуля collections создаёт кортежоподобный класс с именованными полями. Экземпляры неизменяемы.


from collections import namedtuple

Point = namedtuple('Point', ['x', 'y'])
p = Point(10, 20)
print(p.x, p.y)
# p.x = 30  # Ошибка: невозможно изменить атрибут
  

как писать код на python (как писать код на python)

10 20
  

Python log 2 (логарифм по основанию 2 в python)

Namedtuple поддерживает распаковку, сравнение, имеет метод _replace для создания копии с новыми значениями.

Проблемы:

  • Отсутствие методов экземпляра: для добавления поведения нужно наследоваться от namedtuple, что может быть неудобно.
  • Ограниченная читаемость: при большом количестве полей лучше использовать dataclass.

Цель: лёгкие неизменяемые структуры для координат, настроек, ключей словарей (хешируемые, если поля хешируемы).

Как уменьшить потребление памяти объектами при большом количестве экземпляров?

Объявление __slots__ в классе фиксирует набор атрибутов и убирает словарь экземпляра __dict__, экономя память.


class Point:
    __slots__ = ('x', 'y')
    def __init__(self, x, y):
        self.x = x
        self.y = y

p = Point(1, 2)
print(p.x, p.y)
# print(p.__dict__)  # Ошибка: нет __dict__
  

Python data model (модель данных python)

1 2
  

__slots__ препятствует добавлению новых атрибутов напрямую, что может быть как плюсом (защита от опечаток), так и минусом.

Проблемы:

  • Наследование: если класс-потомок тоже хочет использовать __slots__, нужно повторить все слоты предка.
  • Совместимость с некоторыми библиотеками: например, сериализация (pickle) может потребовать дополнительных настроек.

Цель: оптимизация памяти при создании миллионов однотипных объектов (например, игровые сущности, точки).

- Python локальная переменная (локальные переменные в python)
- Python объекты (объекты в python)
- проверка класса python (проверка типа (класса) объекта в python (isinstance, type))

Расширенные примеры работы с объектами

Магические методы для настройки поведения

Переопределение __str__, __repr__, __eq__ и __hash__ позволяет объектам корректно отображаться, сравниваться и использоваться в множествах и словарях.

Пример

class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __repr__(self):
        return f"Vector({self.x}, {self.y})"

    def __eq__(self, other):
        if not isinstance(other, Vector):
            return NotImplemented
        return self.x == other.x and self.y == other.y

    def __hash__(self):
        return hash((self.x, self.y))

v1 = Vector(1, 2)
v2 = Vector(1, 2)
print(v1)
print(v1 == v2)
print({v1, v2})
  
Vector(1, 2)
True
{Vector(1, 2)}
  

NotImplemented возвращается, если сравнение с другим типом не поддерживается. __hash__ обязателен, если объекты помещаются в хеш-структуры.

Свойства (property) для вычисляемых атрибутов

Декоратор @property превращает метод в атрибут, доступный только для чтения или с проверками.

Пример

class Rectangle:
    def __init__(self, width, height):
        self._width = width
        self._height = height

    @property
    def area(self):
        return self._width * self._height

    @property
    def width(self):
        return self._width

    @width.setter
    def width(self, value):
        if value <= 0:
            raise ValueError("Ширина должна быть положительной")
        self._width = value

r = Rectangle(10, 5)
print(r.area)
r.width = 12
print(r.area)
  
50
60
  

Свойства позволяют реализовать инкапсуляцию без явных геттеров и сеттеров.

Наследование и вызов super()

Использование super().__init__() в классе-наследнике гарантирует инициализацию родительской части.

Пример

class Animal:
    def __init__(self, name):
        self.name = name

class Dog(Animal):
    def __init__(self, name, breed):
        super().__init__(name)
        self.breed = breed

    def speak(self):
        return f"{self.name} говорит Гав!"

d = Dog("Бобик", "Такса")
print(d.speak())
print(d.breed)
  
Бобик говорит Гав!
Такса
  

При множественном наследовании super() следует порядку MRO (Method Resolution Order).

Статические методы и методы класса

@staticmethod не получает ссылку на класс или экземпляр, @classmethod принимает класс (cls) как первый аргумент.

Пример

class MathUtils:
    @staticmethod
    def add(a, b):
        return a + b

    @classmethod
    def create_from_string(cls, s):
        a, b = map(int, s.split(','))
        return cls()  # возвращает экземпляр класса

print(MathUtils.add(3, 4))
  
7
  

Статические методы подходят для утилит, а класс-методы - для альтернативных конструкторов.

Использование dataclass с настройками

Параметры декоратора: order=True для сортировки, frozen=True для неизменяемости.

Пример

from dataclasses import dataclass, field

@dataclass(order=True, frozen=True)
class Product:
    name: str
    price: float
    tags: list = field(default_factory=list)

p1 = Product("Кофе", 250)
p2 = Product("Чай", 150)
print(p1 > p2)
# p1.price = 300  # Ошибка: frozen экземпляр
  
True
  

Параметр frozen делает экземпляры хешируемыми (если все поля хешируемы).

Объекты в Python - comments

En
Python объекты (python)