Разбираемся с методами объектов в Python

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

Основные типы методов в Python

Метод в Python - это функция, определенная внутри класса и предназначенная для работы с объектами этого класса. Самый распространенный тип - метод экземпляра. Он первым аргументом принимает self - ссылку на текущий экземпляр.

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

    def introduce(self):
        return f"Меня зовут {self.name}, мне {self.age} лет."

p = Person("Анна", 25)
print(p.introduce())

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

Меня зовут Анна, мне 25 лет.

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

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

Если метод объявлен без self, Python попытается передать экземпляр как первый позиционный аргумент, что приведет к несоответствию количества аргументов.

class Person:
    def introduce():  # self отсутствует
        return "Ошибка"
p = Person()
p.introduce()  # TypeError: introduce() takes 0 positional arguments but 1 was given

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

Как сделать метод, который принадлежит классу, а не экземпляру?

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

class User:
    def __init__(self, username, email):
        self.username = username
        self.email = email

    @classmethod
    def from_email(cls, email):
        name = email.split('@')[0]
        return cls(name, email)

u = User.from_email("ivan@example.com")
print(u.username)  # ivan

метод call python (метод __call__ в python)

ivan

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

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

Когда нужен метод, не зависящий ни от экземпляра, ни от класса?

Статический метод, помеченный @staticmethod, - это обычная функция внутри класса. Он не принимает ни self, ни cls. Используется для группировки вспомогательных функций, имеющих отношение к классу.

class MathUtils:
    @staticmethod
    def is_even(n):
        return n % 2 == 0

print(MathUtils.is_even(4))  # True

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

True

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

Ошибка - пытаться обратиться к атрибутам экземпляра или класса внутри статического метода. Это невозможно, так как статический метод не имеет ссылок на объекты. Для работы с атрибутами класса используйте @classmethod.

Как вычислить значение атрибута динамически и контролировать его изменение?

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

class Circle:
    def __init__(self, radius):
        self._radius = radius

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

    @property
    def radius(self):
        return self._radius

    @radius.setter
    def radius(self, value):
        if value <= 0:
            raise ValueError("Радиус должен быть положительным")
        self._radius = value

c = Circle(5)
print(c.area)  # 78.5
c.radius = 10
print(c.area)  # 314.0
# c.radius = -1  # ValueError

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

78.5
314.0

Python call method (вызов метода в python)

Частая ошибка - определить сеттер без геттера. Если геттер уже существует с тем же именем, сеттер добавляется с помощью @имя.setter. Если же геттер не объявлен, Python не даст использовать сеттер. Также нельзя использовать свойство с тем же именем, что и атрибут (например, self.radius вместо self._radius), иначе возникнет рекурсия.

Как переопределить стандартное поведение объектов?

Специальные (магические) методы, окруженные двойными подчеркиваниями, позволяют классу взаимодействовать с встроенными операциями Python. Самые популярные: __init__ (конструктор), __str__ (строковое представление), __add__ (сложение), __repr__ (представление для разработчика).

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):
        if not isinstance(other, Vector):
            return NotImplemented
        return Vector(self.x + other.x, self.y + other.y)

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

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

Python класс данных (класс данных в python)

Vector(4, 6)
False

Ошибка - забыть возвращать NotImplemented для неподдерживаемых типов в __add__. Если возвращается NotImplemented, Python пытается обработать операцию у второго операнда. Возврат False может привести к некорректному поведению.

- класс python определение (определение классов в python)
- Self method python (параметр self в методах python)
- приватные атрибуты python (приватные атрибуты в python)

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

Класс с комбинацией различных методов

Пример
class Employee:
    company = "TechCorp"

    def __init__(self, name, salary, department):
        self.name = name
        self.salary = salary
        self.department = department

    @property
    def annual_bonus(self):
        return self.salary * 0.1

    @classmethod
    def from_dict(cls, data):
        return cls(data['name'], data['salary'], data['department'])

    @staticmethod
    def is_salary_valid(salary):
        return salary > 0

    def __repr__(self):
        return f"Employee({self.name}, {self.department})"

    def __eq__(self, other):
        if not isinstance(other, Employee):
            return NotImplemented
        return self.name == other.name and self.department == other.department

data = {'name': 'Иван', 'salary': 50000, 'department': 'IT'}
emp1 = Employee.from_dict(data)
print(emp1)
print(emp1.annual_bonus)
print(Employee.is_salary_valid(emp1.salary))
emp2 = Employee.from_dict(data)
print(emp1 == emp2)
Employee(Иван, IT)
5000.0
True
True

Использование свойства для вычисления возраста

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

    @property
    def age(self):
        from datetime import datetime
        return datetime.now().year - self._birth_year

    @age.setter
    def age(self, new_age):
        if new_age < 0 or new_age > 150:
            raise ValueError("Некорректный возраст")
        from datetime import datetime
        self._birth_year = datetime.now().year - new_age

p = Person("Ольга", 1990)
print(p.age)
p.age = 20
print(p._birth_year)
34
2004

Метод класса как фабрика: создание объектов из строки

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

    @classmethod
    def from_polar(cls, radius, angle):
        import math
        x = radius * math.cos(angle)
        y = radius * math.sin(angle)
        return cls(x, y)

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

p = Point.from_polar(10, math.pi/4)
print(p)
Point(7.07, 7.07)

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

Пример
class StringUtils:
    @staticmethod
    def is_palindrome(s):
        s = ''.join(c.lower() for c in s if c.isalnum())
        return s == s[::-1]

print(StringUtils.is_palindrome("А роза упала на лапу Азора"))
True

Магический метод __call__ для функторов

Пример
class Adder:
    def __init__(self, step):
        self.step = step

    def __call__(self, x):
        return x + self.step

add_five = Adder(5)
print(add_five(10))
15

Методы в программе на Python - comments

En
метод в программе python (python)