Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Как объявляется getter?
Getter — это метод, который позволяет безопасно получить значение приватного атрибута объекта. В Python есть несколько способов объявления getter'ов:
1. Использование @property декоратора (современный подход)
Это самый "pythonic" способ, рекомендуемый в Python:
class Person:
def __init__(self, age):
self._age = age # Приватный атрибут (условно)
@property
def age(self):
"""Getter для возраста"""
return self._age
# Использование
person = Person(25)
print(person.age) # 25
Преимущества:
- Выглядит как обычный атрибут, но это метод
- Можно добавить логику без изменения кода клиента
- Pythonic и читаемо
2. Property с setter'ом и deleter'ом
Полная версия с контролем значений:
class BankAccount:
def __init__(self, balance):
self._balance = balance
@property
def balance(self):
"""Getter: получить баланс"""
return self._balance
@balance.setter
def balance(self, value):
"""Setter: установить баланс с проверкой"""
if value < 0:
raise ValueError("Баланс не может быть отрицательным")
self._balance = value
@balance.deleter
def balance(self):
"""Deleter: удалить баланс"""
print(f"Баланс {self._balance} был удален")
del self._balance
# Использование
account = BankAccount(1000)
print(account.balance) # 1000 (getter)
account.balance = 1500 # 1500 (setter)
# account.balance = -100 # ValueError!
del account.balance # Выведет: Баланс 1500 был удален
3. Простой метод getter (старый стиль, но всё ещё используется)
Просто метод с префиксом get_:
class Rectangle:
def __init__(self, width, height):
self._width = width
self._height = height
def get_width(self):
"""Getter для ширины"""
return self._width
def get_height(self):
"""Getter для высоты"""
return self._height
def get_area(self):
"""Вычисляемое свойство"""
return self._width * self._height
# Использование
rectangle = Rectangle(4, 5)
print(rectangle.get_width()) # 4
print(rectangle.get_area()) # 20
Минусы:
- Многословно
- Не pythonic
- Требует вызова как метод ()
4. Getter с кэшированием (вычисляется один раз)
Для дорогих операций:
class DataProcessor:
def __init__(self, data):
self._data = data
self._cache = None
@property
def processed_data(self):
"""Вычисляется один раз и кэшируется"""
if self._cache is None:
print("Выполняю дорогую операцию...")
self._cache = [x * 2 for x in self._data] # Имитация обработки
return self._cache
# Использование
processor = DataProcessor([1, 2, 3])
print(processor.processed_data) # Выполняю дорогую операцию... [2, 4, 6]
print(processor.processed_data) # [2, 4, 6] (без повторного вычисления)
5. Computed property (вычисляется при каждом вызове)
Для значений, зависящих от других атрибутов:
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def radius(self):
return self._radius
@property
def area(self):
"""Площадь вычисляется из радиуса"""
import math
return math.pi * self._radius ** 2
@property
def circumference(self):
"""Окружность вычисляется из радиуса"""
import math
return 2 * math.pi * self._radius
# Использование
circle = Circle(5)
print(f"Радиус: {circle.radius}") # 5
print(f"Площадь: {circle.area:.2f}") # 78.50
print(f"Окружность: {circle.circumference:.2f}") # 31.42
6. Property с описанием и документацией
Добавляем docstring для объяснения:
class Student:
def __init__(self, name, grades):
self._name = name
self._grades = grades
@property
def name(self):
"""str: Имя студента (только для чтения)"""
return self._name
@property
def average_grade(self):
"""float: Средняя оценка студента
Returns:
float: Средняя из всех оценок
Raises:
ValueError: Если нет оценок
"""
if not self._grades:
raise ValueError("У студента нет оценок")
return sum(self._grades) / len(self._grades)
# Использование с help()
help(Student.average_grade)
7. Getter с использованием getattr
Динамический доступ к атрибутам:
class DynamicObject:
def __init__(self):
self._data = {"name": "John", "age": 30}
def __getattr__(self, name):
"""Вызывается, когда атрибут не найден"""
if name in self._data:
return self._data[name]
raise AttributeError(f"Атрибут '{name}' не найден")
# Использование
obj = DynamicObject()
print(obj.name) # "John"
print(obj.age) # 30
# print(obj.unknown) # AttributeError
8. Сравнение подходов
# Способ 1: @property (РЕКОМЕНДУЕТСЯ)
class UserProperty:
def __init__(self, email):
self._email = email
@property
def email(self):
return self._email
user1 = UserProperty("john@example.com")
print(user1.email) # john@example.com
# Способ 2: getter метод (старый стиль)
class UserGetter:
def __init__(self, email):
self._email = email
def get_email(self):
return self._email
user2 = UserGetter("jane@example.com")
print(user2.get_email()) # jane@example.com
# Способ 3: public атрибут (небезопасно)
class UserPublic:
def __init__(self, email):
self.email = email # Нет защиты
user3 = UserPublic("bob@example.com")
user3.email = 123 # Кто угодно может присвоить неправильное значение
9. Getter с валидацией в setter'е
class Email:
def __init__(self, value):
self._email = None
self.email = value # Использует setter с валидацией
@property
def email(self):
"""Getter: получить email"""
return self._email
@email.setter
def email(self, value):
"""Setter: установить email с валидацией"""
if "@" not in value or "." not in value:
raise ValueError(f"Некорректный email: {value}")
self._email = value
# Использование
email = Email("user@example.com")
print(email.email) # user@example.com
# email.email = "invalid" # ValueError
10. Использование @functools.cached_property (Python 3.8+)
Автоматическое кэширование:
from functools import cached_property
class LargeDataProcessor:
def __init__(self, data):
self.data = data
@cached_property
def processed_data(self):
"""Вычисляется один раз и кэшируется навсегда"""
print("Обрабатываю данные...")
return [x * 2 for x in self.data]
# Использование
processor = LargeDataProcessor([1, 2, 3])
print(processor.processed_data) # Обрабатываю данные... [2, 4, 6]
print(processor.processed_data) # [2, 4, 6] (из кэша)
Рекомендации:
- @property — стандартный и рекомендуемый способ в Python
- get_ методы* — используй редко, в особых случаях
- @cached_property — для дорогих вычислений (Python 3.8+)
- getattr — для динамических атрибутов
- Всегда используй _prefix — чтобы указать на "приватность"
В Python getter'ы объявляются через @property декоратор — это самый pythonic и современный способ.