Методы Python: экземплярные, классовые, статические и специальные

Раздел: Объектно-ориентированное программирование -> Объектно-ориентированное программирование

Основы методов объектов в Python

Метод - это функция, определённая внутри класса и предназначенная для работы с данными объекта или самого класса. В Python существуют разные виды методов, каждый из которых решает свою задачу. Ниже рассматривается основной подход (метод экземпляра) и несколько альтернативных вариантов.

Как определить метод, который обращается к атрибутам конкретного объекта?

Самый распространённый тип - метод экземпляра. Он всегда принимает первым параметром self - ссылку на текущий объект. Через self можно читать и изменять атрибуты экземпляра.

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

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

p = Person('Анна')
print(p.greet())

атрибуты класса python (атрибуты классов и объектов в python)

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

библиотека классов python (библиотека классов в python)

Типичная ошибка: забыть указать self в определении метода. Если написать def greet(): ..., Python передаст объект как первый аргумент, что вызовет ошибку «missing 1 required positional argument».

Решение: всегда добавлять self первым параметром, даже если этот параметр не используется внутри метода.

Как создать метод, работающий с классом в целом, а не с его экземпляром?

Для этого используется декоратор @classmethod. Первый параметр такого метода - cls (ссылка на класс). Методы класса часто применяются для альтернативных конструкторов или изменения состояния, общего для всех экземпляров.

class Counter:
    total = 0

    @classmethod
    def increment(cls, amount=1):
        cls.total += amount

Counter.increment()
Counter.increment(5)
print(Counter.total)

метод объекта python (методы объектов в python)

6

Python структура объекта (структура объекта в python)

Типичная ошибка: использование self вместо cls. Это не приведёт к синтаксической ошибке, но метод потеряет связь с классом.

Решение: для методов, которые не нуждаются в информации об объекте, но работают с атрибутами класса, выбирать @classmethod.

Как определить утилитарный метод внутри класса, не требующий доступа ни к self, ни к cls?

Такой метод помечается декоратором @staticmethod. Он ведёт себя как обычная функция, но находится в пространстве имён класса. Статические методы удобны для вспомогательных вычислений, связанных с классом по смыслу.

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

print(MathUtils.add(3, 4))

Python создание объектов (создание объектов в python)

7

Self object python (объект self в python)

Типичная ошибка: попытка обратиться к self или cls внутри статического метода. Это вызовет ошибку, так как эти переменные не определены.

Решение: если методу нужны данные класса или экземпляра, следует использовать метод экземпляра или класса, а не статический.

Как переопределить стандартное поведение объектов (строковое представление, инициализация)?

В Python есть специальные методы (dunder-методы), заключённые в двойные подчёркивания. Они позволяют задать, как объект ведёт себя в различных контекстах: инициализация __init__, строковое представление __str__ и __repr__, сравнение __eq__ и другие.

class Book:
    def __init__(self, title, author):
        self.title = title
        self.author = author

    def __str__(self):
        return f'"{self.title}" - {self.author}'

b = Book('Мастер и Маргарита', 'Булгаков')
print(b)

Object attribute python (атрибуты объекта в python)

"Мастер и Маргарита" - Булгаков

Типичная ошибка: неверное количество аргументов в специальном методе. Например, __init__ должен иметь хотя бы self, а при создании объекта передаются аргументы после self.

Решение: сверяться с документацией по нужному методу и чётко прописывать параметры.

- Class method python (методы классов в python)
- Python object methods (методы объектов в python)
- класс python определение (определение классов в python)

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

Здесь представлены более тонкие возможности, которые часто упускаются из виду, но добавляют гибкости коду.

Методы как свойства (property)

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

Пример
class Circle:
    def __init__(self, radius):
        self._radius = radius

    @property
    def area(self):
        return 3.14159 * self._radius ** 2

c = Circle(5)
print(c.area)
78.53975

Перегрузка операторов (методы __add__, __eq__ и др.)

Позволяет использовать объекты с операторами +, ==, [] и т.д. Например, векторное сложение:

Пример
class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __add__(self, other):
        return Vector(self.x + other.x, self.y + other.y)

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

v1 = Vector(1, 2)
v2 = Vector(3, 4)
print(v1 + v2)
Vector(4, 6)

Вызов объекта как функции (__call__)

Метод __call__ позволяет экземпляру вести себя как функция. Это удобно для замыканий или объектов-декораторов:

Пример
class Multiplier:
    def __init__(self, factor):
        self.factor = factor

    def __call__(self, x):
        return x * self.factor

double = Multiplier(2)
print(double(5))
10

Методы для цепочек вызовов (fluent interface)

Возвращая self из метода, можно строить цепочки вызовов:

Пример
class Query:
    def __init__(self):
        self._conditions = []

    def where(self, condition):
        self._conditions.append(condition)
        return self

    def order_by(self, field):
        self._order = field
        return self

    def execute(self):
        return f'SELECT * FROM table WHERE {" AND ".join(self._conditions)} ORDER BY {self._order}'

q = Query().where('age > 18').where('status = active').order_by('name')
print(q.execute())
SELECT * FROM table WHERE age > 18 AND status = active ORDER BY name

Методы с динамическим именем (getattr)

Функция getattr позволяет вызывать метод по строковому имени. Это бывает нужно при работе с плагинами или командами:

Пример
class Actions:
    def say_hello(self):
        return 'Hello!'

    def say_goodbye(self):
        return 'Goodbye!'

a = Actions()
cmd = 'say_hello'
method = getattr(a, cmd, None)
if method:
    print(method())
Hello!

Абстрактные методы (abc)

Модуль abc позволяет объявить метод, который должен быть переопределён в подклассе. Это основа для шаблонного проектирования:

Пример
from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def area(self):
        pass

class Square(Shape):
    def __init__(self, side):
        self.side = side

    def area(self):
        return self.side ** 2

s = Square(4)
print(s.area())
16

Методы как объекты первого класса (привязка и отвязка)

Метод можно сохранить в переменную и передать как аргумент. При этом контекст объекта сохраняется, если метод извлекается из экземпляра:

Пример
class Greeter:
    def __init__(self, name):
        self.name = name

    def greet(self):
        return f'Привет, {self.name}'

g = Greeter('Мир')
bound_method = g.greet
print(bound_method())
Привет, Мир

Можно также вызвать метод через класс, передав экземпляр явно:

Пример
unbound_method = Greeter.greet
print(unbound_method(g))
Привет, Мир

Методы объектов в Python - comments

En
Python object methods (python)