О свойствах (property) в Python
В Python, есть такая штука, как свойства (property) — это объекты, которые реализуют descriptor-протокол и позволяют проделывать следующее:
class Person(object):
def __init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name
@property
def full_name(self):
return " ".join([self.first_name, self.last_name])
person = Person("Andrey", "Popp")
person.full_name # "Andrey Popp"
Это реализация attribute getter/setter шаблона. То есть, обращаюсь к full_name как к аттрибуту, мы неявно вызываем соответствующий метод и его результат как бы становится значением аттрибута. Почему “как бы”? Потому что он будет заново вычисляться при каждом обращении к full_name.
Я стараюсь никогда не использовать свойства, в тех случаях, когда для их вычисления приходится производить какие-то побочные эффекты, будь-то I/O или даже просто изменение какой-нибудь структуры данных.
Операция обращения к аттрибуту (а именно так выглядит работа с property) по своей семантике должна быть “дешёвой”. Со свойствами можно наворотить следующее — представьте себе, что вы, находясь в консоли Python и обращаетесь к некоему аттрибуту myobj.some_info, в результате чего отправляется запрос в БД и вычисление свойства происходит в течении n секунд — крайне неприятно.
Одна из библиотек, с которыми я работал и которая не следует вышеупомянутой рекомендации — SQLAlchemy. Там можно настроить маппинг таблиц на модели таким образом, что при обращении к свойствам последних их значения будут запрашиваться из БД отдельным запросом. Получается если обратиться к такому свойству в цикле из 100 итераций, то будет сделано 100 отдельных запросов к БД и при этом, программист читающий код, может этого совершенно не заметить.
Отсюда вердикт — если для вычисления свойства нужно произвести побочные эффекты, то лучше сделать это свойство методом.
P.S. Кстати, аналогичное суждение верно и в языках на подобии Scala, где можно опустить () при вызове функций, которые не принимают никаких параметров — я считаю, что если функция производит некие побочные эффекты, то () после её вызова необходимо оставить.