#python-3.x
#python-3.x
Вопрос:
У меня есть класс как таковой:
class Line:
def __init__(self, text: str):
self.text = text
Строка в моем случае может иметь много features
. Например,
- Строка считается длинной, если в ней более 50 символов.
- Если строка содержит символы, отличные от ascii, то флаг устанавливается как non_ascii = True и так далее
- Найдите все URL-адреса в строке
Я могу реализовать их в терминах методов класса:
class Line:
def __init__(self, text: str):
self.text = text
def is_ascii(self):
# check and return
def is_long(self):
# check and return
def urls(self):
# find and return urls
Проблема, с которой я сталкиваюсь, заключается в том, что мне нужно выполнять вызовы метода для объекта Line несколько раз на разных этапах процесса (некоторые вызовы методов довольно сложны с точки зрения вычислений).
Что я хотел бы иметь, так это то, что при инициализации я хотел бы, чтобы объект Line имел предварительно заполненные атрибуты, такие как is_ascii, is_long, urls, чтобы к ним можно было обращаться несколько раз без необходимости вычислять их каждый раз при обращении к ним.
class Line:
def __init__(self, text: str):
self.text = text
self.is_ascii = do some processing on self.text, and assign value
self.is_long = do some processing on self.text, and assign value
self.urls = do some processing on self.text, and assign value
Я не уверен, имеет ли смысл иметь всю эту логику внутри блока инициализации. Как бы мне добиться этого «питоническим» способом?
Комментарии:
1. @Carcigenicate: спасибо за ответ. Если это возможно, не могли бы вы показать, как будет работать кэширование? Я не очень хорошо разбираюсь в Python.
Ответ №1:
Вы могли бы просто использовать методы, которые вы выполняете, и вызывать их изнутри __init__
:
class Line:
def __init__(self, text: str):
self.text = text
self.is_ascii = self.calc_is_ascii(self.text)
self.is_long = self.calc_is_long(self.text)
self.urls = self.calc_urls(self.text)
def calc_is_ascii(self):
# check and return
def calc_is_long(self):
# check and return
def calc_urls(self):
# find and return urls
Вы также могли бы сделать так, чтобы при вызове метода он проверял, было ли значение уже вычислено, и использовал кэшированное значение, в противном случае он вычисляет и кэширует его:
class Line:
def __init__(self, text: str):
self.text = text
self.is_ascii = None
self.is_long = None
self.urls = None
def calc_is_ascii(self):
if self.is_ascii is None:
# Do expensive calculation of self.is_ascii
self.is_ascii = expensive_result
# Use the cached, previously calculated value
return self.is_ascii
# Then the same pattern for other methods
Это имеет то преимущество, что если один из атрибутов никогда не нужен, работа по его вычислению не выполняется.
Я инициализирую атрибуты None
. Если они None
позже, я знаю, что они еще не были вычислены. Если это не так None
, я знаю, что они уже были вычислены, поэтому я могу просто вернуть вычисленный результат. Это, конечно, предполагает, что None
это недопустимое значение.