Атрибуты и методы
Атрибуты и методы
В предыдущем уроке мы создали простые классы и добавляли атрибуты вручную. Теперь разберём более глубоко: как атрибуты хранятся, чем экземплярные атрибуты отличаются от атрибутов класса, и как методы взаимодействуют с данными объекта.
Атрибуты экземпляра через self
Правильный способ определить атрибуты экземпляра — присвоить их через self внутри метода. Самое естественное место — метод __init__ (инициализатор), который вызывается автоматически при создании объекта:
class Dog:
def __init__(self, name, breed, age):
self.name = name # атрибут экземпляра
self.breed = breed
self.age = age
buddy = Dog("Buddy", "Лабрадор", 3)
rex = Dog("Rex", "Овчарка", 5)
print(buddy.name) # Buddy
print(rex.name) # Rex — у каждого объекта свой name
self.name = name создаёт атрибут name у конкретного экземпляра. Разные объекты хранят разные значения независимо.
Атрибуты класса
Атрибуты, определённые прямо в теле класса (вне методов), принадлежат классу, а не отдельному экземпляру:
class Dog:
species = "Canis lupus familiaris" # атрибут класса
count = 0 # счётчик
def __init__(self, name):
self.name = name
Dog.count += 1 # изменяем атрибут КЛАССА через имя класса
print(Dog.count) # 0
d1 = Dog("Buddy")
d2 = Dog("Rex")
print(Dog.count) # 2
Атрибуты класса используют для данных, общих для всех экземпляров: константы, счётчики, конфигурация.
Методы экземпляра
Обычный метод — принимает self как первый аргумент и работает с данными конкретного объекта:
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
def perimeter(self):
return 2 * (self.width + self.height)
def describe(self):
return f"Прямоугольник {self.width}×{self.height}"
r = Rectangle(4, 6)
print(r.area()) # 24
print(r.perimeter()) # 20
print(r.describe()) # Прямоугольник 4×6
Методы изменяют состояние
Методы могут не только читать, но и изменять атрибуты объекта:
class BankAccount:
def __init__(self, owner, balance=0):
self.owner = owner
self.balance = balance
def deposit(self, amount):
if amount <= 0:
raise ValueError("Сумма должна быть положительной")
self.balance += amount
def withdraw(self, amount):
if amount > self.balance:
raise ValueError("Недостаточно средств")
self.balance -= amount
def info(self):
return f"{self.owner}: {self.balance} руб."
account = BankAccount("Алиса", 1000)
account.deposit(500)
account.withdraw(200)
print(account.info()) # Алиса: 1300 руб.
Вызов метода изнутри класса
Метод может вызвать другой метод через self:
class Circle:
def __init__(self, radius):
self.radius = radius
def area(self):
import math
return math.pi * self.radius ** 2
def diameter(self):
return self.radius * 2
def summary(self):
return f"r={self.radius}, d={self.diameter()}, S={self.area():.2f}"
c = Circle(5)
print(c.summary()) # r=5, d=10, S=78.54
dict — словарь атрибутов
Атрибуты экземпляра хранятся в словаре __dict__:
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
p = Point(3, 4)
print(p.__dict__) # {'x': 3, 'y': 4}
Это полезно для отладки и сериализации.
Итог
self.attr = valueв методе — атрибут экземпляра; уникален для каждого объекта.ClassName.attr = valueв теле класса — атрибут класса; общий для всех.- Методы работают с данными объекта через
self. - Методы могут изменять атрибуты (
self.balance += amount) и вызывать другие методы (self.diameter()). obj.__dict__— словарь всех атрибутов экземпляра.
В следующем уроке подробно изучим метод __init__ — конструктор класса, который вызывается при создании объекта.