Вопрос

Я создаю собственные представления на основе классов для проекта Django и столкнулся с дизайнерским решением, касающимся атрибутов.

Геттерные функции

Я посмотрел на общие представления Django и увидел, что существует довольно много классов, которые предоставляют как переменные класса, так и собственные функции получения. например.

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()

экземпляр.__dict__

Я планирую использовать эти значения внутри шаблона.Я передаю экземпляры расширяющихся представлений в шаблон и отображаю атрибуты следующим образом:

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__.

Вопрос

Чтобы перейти к вопросу, какой из перечисленных подходов является лучшим выбором?

  • Метод получения хорош, поскольку позволяет super()-вызов родительской функции-получателя, но в большинстве моих случаев это, вероятно, никогда не понадобится.
  • Подход, основанный на свойствах, намного проще и требует написания меньшего количества кода.я не могу super()-вызовите функцию свойства родителя.В большинстве случаев мне не понадобится такое поведение, но могут быть случаи, когда мне понадобится super() функциональность, поэтому будет смесь простых атрибутов, которые можно переопределить с помощью свойств и пользовательских функций получения.
  • Последний подход требует еще меньше кода, чем подход, основанный на свойствах, но я сомневаюсь, что это хороший стиль.
Это было полезно?

Решение

Подход, основанный на свойствах, намного проще и требует написания меньшего количества кода.Однако я не могу super() вызвать функцию свойства родителя.

На самом деле вы можете получить доступ к родительским свойствам через super():

class A(object):
    @property
    def prop(self):
        return 'A.prop'

class B(A):
    @property
    def prop(self):
        return '%s - %s' % (super(B, self).prop, 'B.prop')

>>> b = B()
>>> b.prop
'A.prop - B.prop'
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top