Chcę być w stanie uchwycić fakty takie jak Bob was born in 2000
i Bill's birthday is May 7th
.
W obu przykładach znamy tylko część daty urodzenia osoby. W jednym przypadku znamy tylko rok; w innym przypadku znamy miesiąc i dzień, ale nie rok.
Jak przechwycić te informacje?
Kilka przykładów tego, jak to może działać:
Wyobraź sobie bibliotekę podobną do datetime, która pozwoliła None w polach reprezentować nieznane. Mogę mieć kod podobny do następującego:
date_a = date(2000, 5, None)
date_b = date(2000, 6, None)
difference = date_b - date_a
assert difference.min.days == 1
assert difference.max.days == 60 # Or something close to 60.
assert equal(date_a, date_b) == False
date_c = date(2000, 5, None)
assert equal(date_a, date_c) == Maybe
To tylko przykład tego, jak może się zachowywać. Niekoniecznie chcę tego precyzyjnego zachowania.
Odpowiedzi:
Po pierwsze, kiedy zaczniesz rozkładać daty na ich składniki składowe, nie będą one już datami.
W ten sam sposób, w jaki nie jest możliwe usunięcie funkcji za pośrednictwem podklas bez zerwania OOP, nie można mieszać dat i ułamków dat bez powodowania zamieszania (lub, co gorsza), czyniąc je kompatybilnymi jak w twoim przykładzie kodu, nie psując niczego innego.
Jeśli chcesz uchwycić rok, co jest nie tak z obiektem zawierającym prostą liczbę całkowitą? Jeśli chcesz uchwycić miesiąc i dzień, dlaczego nie uchwycić wyliczenia miesiąca i liczby całkowitej? Może nawet przechowujesz je wewnętrznie w obiekcie daty, aby uzyskać prawidłowe sprawdzanie granic (np. 31 lutego nie ma sensu). Wystaw jednak inny interfejs.
Dlaczego chcesz porównać datę z rokiem, aby sprawdzić, czy są one takie same, większe czy mniejsze? To nie ma sensu: nie ma wystarczających informacji, aby dokonać tego porównania. Istnieją jednak inne porównania, które mogą mieć sens (jest to pseudokod):
źródło
Drugi komentarz Roberta Harveya zawiera właściwą odpowiedź, ale pozwólcie, że rozwinę ją nieco.
Rok urodzenia i daty narodzin są zupełnie innymi podmiotami, więc nie musisz (a właściwie nie powinieneś) używać tego samego mechanizmu w obu przypadkach.
W przypadku dat urodzenia możesz opracować
BirthDate
typ danych (lub byćYearlyRecurringDate
może nie jestem w stanie wymyślić teraz przyzwoitego nazwiska), który zawierałby tylkodate
stały rok, na przykład 2000 zgodnie z konwencją. Rok 2000 to dobry wybór, ponieważ był to skok, więc nie zawiedzie ludzi, których urodziny przypadają 28 lutego.Przez wiele lat urodzeń, można opracować
BirthYear
typ danych (lub ewentualnie jestApproximateDate
typ danych), które zawierajądate
, oraz wskaźnik dokładności:Year
,Month
,Full
.Zaletą tych podejść jest to, że w centrum rzeczy, które nadal utrzymujesz
date
, możesz nadal wykonywać arytmetykę dat.źródło
Wierzę, że to, co opisujesz, stanowiłoby zastąpienie
datetime
modułu, który implementujedatetime.datetime
atrybuty (rok, miesiąc itp.) Jako wartości z pomiarem niepewności (a nie tylko wartości).Istnieją pakiety Pythona, które pomagają w obliczaniu niepewnych liczb (np. Pakiet niepewności ), i być może nie byłoby zbyt trudne zrobienie rozwidlenia,
datetime
które wykorzystuje niepewność dla każdego atrybutu. Ja też chciałbym je zobaczyć, a może nawet by się przydały. Z pewnością można argumentować za włączeniem audatetime
do wyżej wspomnianego pakietu niepewności.Twoje przykłady mogą wyglądać następująco:
„Wartości sygnałów” mają wiele problemów, ale dodatkowo można niepewnie przedstawiać rzeczy, których wartości sygnałów nie mogą:
Inną kwestią jest to, że aby być bardziej precyzyjnym, niepewności powinny faktycznie być tego rodzaju
timedelta
. Pozostawiam to jako ćwiczenie dla czytelnika, aby znaleźć zwięzły i kompletny konstruktor doudatetime
korzystania ztimedelta
niepewności.Tak więc ostatecznie powiedziałbym, że to, co opisujesz, jest „łatwe” do modelowania z niepewnością, ale implementacja
udatetime
jest praktycznie dość trudna. Większość wybierze „łatwą” trasę i rozbije czas na podzespoły i niezależnie śledzi niepewność na nich, ale jeśli czujesz się ambitny,uncertainties
pakiet (lub inny) może być zainteresowany prośbą o ściągnięcieudatetime
.źródło
Dlaczego nie stworzyć klasy „kropka”, która implementuje strukturę od do do.
„Bob urodził się w 2000 roku” ->
Następnie możesz zaimplementować różne metody wyszukiwania, np. Od nawiasów do dat. Atrybut fuzz daje użyteczne wskazanie, jak dokładna jest data, dzięki czemu można określić fuzz == 1 dla dokładnych dopasowań lub fuzz == 31 w ciągu około miesiąca.
źródło