#python-3.x #class #properties #setter
#python-3.x #класс #свойства #установщик
Вопрос:
У меня есть такой класс, как этот:
class Ticket:
def __init__(self, ticket):
self._subject = ticket.subject
self._oem = self.oem()
@property
def oem(self):
return self._oem
@oem.setter
def oem(self):
#set oem value by extracting it from subject using regex
self._oem = re.findall('<OEM: (.*?)>', self._subject)[0].strip()
Однако при создании объекта,
obj = Ticket(test_ticket)
Я получаю сообщение об ошибке,
AttributeError: 'Ticket' object has no attribute '_oem'
Я рассматривал похожие вопросы, но они не задают того же, что и я.
Я хочу установить значение для oem в __init__
методе, используя значение из предыдущей переменной, а не передавая значение извне.
Как мне решить эту проблему?
Комментарии:
1. Что вы ожидаете сделать
self._oem = self.oem()
? Также обратите внимание, что в вашем установщике отсутствует аргумент.
Ответ №1:
Установщик свойств должен принять значение, оно будет вызываться при присвоении атрибуту, например
t = Ticket()
t.oem = value # this would call call Ticket.oem(t, value)
Если это свойство просто использует данные из self._subject
, тогда вообще не пишите сеттер. Вместо этого сделайте атрибут динамически вычисляемым свойством, доступным только для чтения, например:
class Ticket:
def __init__(self, ticket):
self._subject = ticket.subject
@property
def oem(self):
return re.findall('<OEM: (.*?)>', self._subject)[0].strip()
Комментарии:
1. Хорошо, понял. Но каждый раз, когда мне нужно получить к нему доступ, будет выполняться некоторая обработка, правильно ли это? Предположим, я знаю, что буду использовать это значение 5 раз, и у меня будет 6 таких значений, которые будут вычисляться динамически. Затем каждый раз, когда будут доступны эти значения, они будут проходить через некоторую логику, которую я определяю. Я полагаю, что это было бы менее эффективно (но, возможно, не заметно)
2. Да, и Python выполняет около 5000 других действий каждый раз, когда вы обращаетесь к нему. Для простого регулярного выражения find это не будет иметь никакого значения, так что не беспокойтесь об этом.
3.
@cached_property
— @wim Я думаю, что это тоже было бы неплохо сделать. Для каждого объекта OEM (или другие свойства) будут оставаться постоянными на протяжении всего срока службы объекта. Ссылка: docs.python.org/3/library /…