Я хочу быть в состоянии захватить факты, как Bob was born in 2000
и Bill's birthday is May 7th
.
В обоих примерах мы знаем только часть даты рождения человека. В одном случае мы знаем только год; в другом случае мы знаем месяц и день, но не год.
Как мне получить эту информацию?
Несколько примеров того, как это может работать:
Представьте себе библиотеку типа datetime, которая позволяет None в полях представлять неизвестных. Я мог бы иметь такой код:
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
Это всего лишь пример того, как он может себя вести. Я не обязательно хочу это точное поведение.
Ответы:
Прежде всего, как только вы начнете разбивать даты на составляющие их компоненты, они больше не будут датами.
Точно так же, как невозможно удалить функциональность через подклассы, не нарушая ООП, невозможно смешивать даты и дробные части, не вызывая путаницы (или того хуже), делая их совместимыми, как в вашем примере кода, не нарушая что-то еще.
Если вы хотите записать год, что не так с объектом, содержащим простое число? Если вы хотите записать месяц и день, почему бы не записать перечисление за месяц и целое число? Может быть, даже хранить их внутри объекта даты, чтобы вы могли правильно проверить границы (например, 31 февраля не имеет смысла). Однако выставьте другой интерфейс.
Почему вы хотите сравнить дату с годом, чтобы увидеть, являются ли они одинаковыми, большими или меньшими? Это не имеет смысла: нет достаточной информации для такого сравнения. Однако есть и другие сравнения, которые могут иметь смысл (это псевдокод):
источник
Второй комментарий Роберта Харви содержит правильный ответ, но позвольте мне немного подробнее остановиться на нем.
Год рождения и даты рождения людей - это совершенно разные сущности, поэтому вам не нужно (и на самом деле не следует) использовать один и тот же механизм для обоих.
Для дат рождения вы можете разработать
BirthDate
тип данных (или, возможно,YearlyRecurringDate
хотя я не могу придумать приличное имя прямо сейчас), который будет содержать толькоdate
с постоянным годом, как 2000 по соглашению. Год 2000 - хороший выбор, потому что это был скачок, поэтому он не подведет людей, чей день рождения 28 февраля.За год рождения, вы можете разработать
BirthYear
тип данных (или , возможно,ApproximateDate
тип данных) , который будет содержатьdate
, и показатель точности:Year
,Month
,Full
.Преимущество этих подходов состоит в том, что в основе вещей, которые вы все еще поддерживаете,
date
вы можете выполнять арифметику дат.источник
Я полагаю, что то, что вы описываете, будет заменой
datetime
модуля, который реализуетdatetime.datetime
атрибуты (год, месяц и т. Д.) Как значения с измерением неопределенности (а не просто значения).Пакеты Python существуют, чтобы помочь с неопределенными числами (например, пакет неопределенностей ), и, возможно, было бы не так уж сложно сделать ответвление
datetime
, использующее неопределенность для каждого атрибута. Я тоже хотел бы увидеть его и, возможно, даже использовать его. Несомненно, можно привести аргумент в пользу включенияudatetime
в пакет вышеупомянутых неопределенностей.Ваши примеры будут примерно такими:
«Значения сигнала» имеют много проблем, но кроме того, вы можете представлять вещи с неопределенностью, что значения сигнала не могут:
Другое соображение состоит в том, что, если быть более точным, неопределенности здесь должны быть типичными
timedelta
. Я оставляю читателю в качестве упражнения выяснение краткого и полного конструктора дляudatetime
использованияtimedelta
неопределенностей.В конечном счете, я бы сказал, что то, что вы описываете, «легко» моделируется неопределенностями, но реализация a
udatetime
практически довольно сложна. Большинство выберет «легкий» маршрут, разбив дату и время на компоненты и самостоятельно отслеживая неопределенность в них, но если вы чувствуете себя амбициозно,uncertainties
пакет (или другой) может заинтересовать запрос на извлечениеudatetime
.источник
Почему бы не создать класс «period», который реализует структуру from.
"Боб родился в 2000 году" ->
Затем вы можете реализовать различные методы поиска, например, заключив в квадратные скобки даты. Атрибут fuzz дает полезную информацию о том, насколько точна дата, поэтому вы можете указать fuzz == 1 для точных совпадений или fuzz == 31 в течение месяца или около того.
источник