вызов установщика из __init__ в Python

#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 /…