Създавам персонализирани изгледи, базирани на класове, за проект на Django и се сблъсках с дизайнерско решение относно атрибути.
Getter функции
Разгледах общите изгледи на 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__
.
Въпрос
За да стигнем до въпроса, кой от изброените подходи е най-добрият избор?
- Подходът на getter е хубав, тъй като позволява
super()
-извикване на функцията getter на родителя, но в повечето от моите случаи това вероятно никога няма да е необходимо. - Подходът на свойствата е много по-прост и води до писане на по-малко код. Въпреки това не мога да
super()
-извикам функцията за собственост на родител. В повечето случаи няма да имам нужда от това поведение, но може да има случаи, в които имам нужда отsuper()
функционалност, така че ще има комбинация от прости атрибути, които могат да бъдат заменени с помощта на свойства и персонализирани функции за получаване. - Последният подход е дори по-малко код от подхода на свойствата, но се съмнявам, че е добър стил.