Mam klasy modelu django, który utrzymuje stan jako prosta właściwość. Dodałem kilka właściwości pomocnika do klasy, aby uzyskać dostęp do stanów zagregowanych - np. is_live
zwraca wartość false, jeśli stan jest jednym z ['closed', 'expired', 'deleted']
itd.Pyton idiomatyczny - właściwość lub metoda?
W wyniku tego mój model ma kolekcję właściwości is_, które wykonują bardzo proste wyszukiwania na wewnętrznych właściwościach obiektu.
Chcę teraz dodać nową właściwość, is_complete
- która jest semantycznie taka sama jak wszystkie inne właściwości - sprawdzanie boolowskie stanu obiektu - jednak ta kontrola wymaga uzależnienia od ładowania (jeden-do-wielu) obiektów podrzędnych, sprawdzanie ich stanu i raportowanie na podstawie wyników - tj. ta właściwość faktycznie wykonuje niektóre (więcej niż jedno) zapytanie bazy danych i przetwarza wyniki.
Czy nadal można modelować jako właściwość (używając dekoratora @property
), czy też powinienem zrezygnować z dekoratora i pozostawić go jako metodę?
Pro użycia właściwości jest to, że jest semantycznie zgodne z wszystkich innych właściwości is_
.
Pro za pomocą metody polega na tym, że wskazuje ona innym programistom, że jest to coś, co ma bardziej złożoną implementację i dlatego powinno być używane oszczędnie (tj. Nie wewnątrz pętli for..
).
from django.db import models
class MyModel(models.Model):
state = CharField(default='new')
@property
def is_open(self):
# this is a simple lookup, so makes sense as a property
return self.state in ['new', 'open', 'sent']
def is_complete(self):
# this is a complex database activity, but semantically correct
related_objects = self.do_complicated_database_lookup()
return len(related_objects)==0
EDIT: I pochodzić z tła .NET pierwotnie, gdzie podział się znakomicie zdefiniowane przez Jeff Atwood jak
„jeśli jest jakaś szansa na cały ten kod może tarło klepsydrę, to na pewno powinna być metodą. "
EDIT 2: nieznaczna zmiana na pytanie - byłoby to problemem, aby go jako metoda, zwana is_complete
, tak że nie są mieszane właściwości i metody z podobnych nazwach - czy to tylko mylące?
Tak - to będzie wyglądać mniej więcej tak:
>>> m = MyModel()
>>> m.is_live
True
>>> m.is_complete()
False
Myślę, że to wciąż ma sens. Czy możesz buforować wynik jako 'self._is_complete' lub czy jest on obliczany wiele razy? Czy możesz wykonywać obliczenia w tle lub czy obliczenia są ważne tylko wtedy, gdy nieruchomość jest oceniana? –
@ JaceBrowning: Miałem dokładnie ten sam pomysł (proszę zobaczyć moją odpowiedź). Zakładałem, że to jest w porządku (jeśli nie, zawsze można je wyczyścić). – Tadeck
@ Tadeck: bez obaw. Nie wiem wystarczająco dużo o 'django', aby wiedzieć, czy ta aplikacja ma sens. –