Я создаю пользовательские представления на основе классов для проекта Django и столкнулся с дизайнерским решением относительно атрибутов.
Функции геттера
Я посмотрел на общие представления Django и увидел, что существует довольно много классов, которые предоставляют как переменные класса, так и пользовательские функции получения. * 1006 например *.
class FormMixin(object):
initial = {}
def get_initial(self):
return self.initial
Это конструктивное решение имеет смысл, потому что таким образом вы можете вызвать super()
в переопределяющем методе расширяющего класса.
Свойства
В моем проекте есть определенные значения, которые я иногда мог бы переопределить, используя простое значение, но иногда они должны создаваться динамически. Сначала я создал методы, аналогичные описанным выше, но потом подумал, что, возможно, свойства - лучший способ сделать это.
class MyBaseView(OtherView):
counter = None
class MyExtendingView(MyBaseView):
counter = 5
class MyOtherExtendingView(MyBaseView):
@property
def counter(self):
return self.other_function()
экземпляр .__ ДИКТ __
Я планирую использовать эти значения внутри шаблона. Я передаю экземпляры расширяющихся видов в шаблон и отображаю атрибуты следующим образом:
context['class_instances'] = [MyExtendingView(), MyOtherExtendingView()]
{% for instance in class_instances %}
{{ instance.counter|default:'' }}
{% endfor %}
Теперь, когда это шаблон, и на самом деле не имеет значения, является ли атрибут экземпляра значением или функцией, я мог бы также написать свои классы следующим образом:
class MyExtendingView(MyBaseView):
counter = 5
class MyOtherExtendingView(MyBaseView):
def counter(self):
return self.other_function()
def counter
заменит старый атрибут на основе значений в instance.__dict__
.
Вопрос
Чтобы перейти к вопросу, какой из перечисленных подходов является лучшим выбором?
- Подход getter хорош, поскольку он позволяет
super()
вызывать функцию get родителя, но в большинстве моих случаев это, вероятно, никогда не понадобится.
- Подход, основанный на свойствах, намного проще и требует меньше кода для написания. Я не могу
super()
-созвать функцию свойства родителя, хотя. Мне не понадобится такое поведение в большинстве случаев, но могут быть случаи, когда мне нужна функциональность super()
, поэтому будет набор простых атрибутов, которые можно переопределить с помощью свойств и пользовательских функций получения.
- Последний подход еще меньше кода, чем подход с использованием свойств, но я сомневаюсь, что это хороший стиль.