Ich möchte in der Lage sein, Fakten wie Bob was born in 2000
und zu erfassen Bill's birthday is May 7th
.
In beiden Beispielen kennen wir nur einen Teil des Geburtsdatums der Person. In einem Fall kennen wir nur das Jahr; im anderen Fall kennen wir den Monat und den Tag, aber nicht das Jahr.
Wie erfasse ich diese Informationen?
Einige Beispiele, wie dies funktionieren könnte:
Stellen Sie sich eine Bibliothek wie datetime vor, in der None in den Feldern Unbekannte darstellen konnte. Ich könnte Code wie den folgenden haben:
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
Dies ist nur ein Beispiel dafür, wie es sich verhalten könnte. Ich möchte nicht unbedingt genau dieses Verhalten.
Antworten:
Sobald Sie Datumsangaben in ihre Bestandteile zerlegen, sind sie zunächst keine Datumsangaben mehr.
Ebenso wie es nicht möglich ist, Funktionen über Unterklassen zu entfernen, ohne OOP zu beschädigen, ist es nicht möglich, Datums- und Datumsbrüche zu mischen, ohne Verwirrung (oder Schlimmeres) zu verursachen, sodass sie wie in Ihrem Codebeispiel kompatibel sind, ohne etwas anderes zu beschädigen.
Wenn Sie ein Jahr erfassen möchten, was ist mit einem Objekt mit einer einfachen Ganzzahl falsch? Wenn Sie einen Monat und einen Tag erfassen möchten, können Sie eine Monatsaufzählung und einen ganzzahligen Tag erfassen. Vielleicht speichern Sie sie sogar intern in einem Datumsobjekt, damit Sie die richtigen Grenzen überprüfen können (z. B. macht der 31. Februar keinen Sinn). Stellen Sie jedoch eine andere Schnittstelle zur Verfügung.
Warum sollten Sie ein Datum mit einem Jahr vergleichen, um festzustellen, ob sie gleich, größer oder kleiner sind? Es macht keinen Sinn: Es gibt nicht genügend Informationen, um diesen Vergleich durchzuführen. Es gibt jedoch andere Vergleiche, die sinnvoll sein könnten (dies ist ein Pseudocode):
quelle
Robert Harveys zweiter Kommentar enthält die richtige Antwort, aber lassen Sie mich etwas näher darauf eingehen.
Das Geburtsjahr und das Geburtsdatum der Menschen sind völlig unterschiedliche Einheiten, sodass Sie nicht für beide den gleichen Mechanismus verwenden müssen (und sollten).
Für Geburtsdaten können Sie einen
BirthDate
Datentyp festlegen (oder möglicherweise einen,YearlyRecurringDate
obwohl ich momentan keinen anständigen Namen finden kann), der nur einendate
mit einem konstanten Jahr enthält, wie z. B. 2000 gemäß Konvention. Das Jahr 2000 ist eine gute Wahl, weil es ein Sprung war, so dass es Menschen, deren Geburtstag am 28. Februar ist, nicht scheitern wird.Für Geburtsjahre können Sie eine ersinnen
BirthYear
Datentyp (oder möglicherweise einenApproximateDate
Datentyp) , die ein enthalten würdedate
, und einen Indikator für die Genauigkeit:Year
,Month
,Full
.Der Vorteil dieser Ansätze besteht darin, dass Sie im Kern der Dinge immer noch eine beibehalten,
date
damit Sie weiterhin Datumsarithmetik durchführen können.quelle
Ich glaube, was Sie beschreiben, wäre ein Ersatz für das
datetime
Modul, das diedatetime.datetime
Attribute (Jahr, Monat usw.) als Werte mit einer Unsicherheitsmessung (und nicht nur als Werte) implementiert .Python-Pakete helfen bei unsicheren Zahlen (z. B. dem Unsicherheitspaket ), und vielleicht wäre es nicht allzu schwierig, eine Verzweigung daraus zu machen
datetime
, die Unsicherheit für jedes Attribut verwendet. Auch ich würde gerne einen sehen und könnte ihn sogar nutzen. Es könnte durchaus ein Argument für die Aufnahme von audatetime
in das oben genannte Unsicherheitspaket vorgebracht werden.Ihre Beispiele wären so etwas wie:
"Signalwerte" haben viele Probleme, aber zusätzlich können Sie Dinge mit Unsicherheit darstellen, die Signalwerte nicht können:
Eine weitere Überlegung ist, dass die Unsicherheiten hier genauer gesagt tatsächlich vom Typ sein sollten
timedelta
. Ich überlasse es dem Leser als Übung, einen präzisen und vollständigen Konstruktor für dieudatetime
Verwendung vontimedelta
Unsicherheiten zu finden.Letztendlich würde ich also sagen, dass das, was Sie beschreiben, "leicht" mit Unsicherheiten modelliert werden kann, aber die Implementierung von a
udatetime
ist praktisch ziemlich schwierig. Die meisten nehmen den "einfachen" Weg und teilen die Datums- und Uhrzeitangaben in Komponenten auf und verfolgen die Unsicherheit auf diesen unabhängig voneinander. Wenn Sie sich jedoch ehrgeizig fühlen, ist dasuncertainties
Paket (oder ein anderes) möglicherweise an einer Pull-Anfrage für interessiertudatetime
.quelle
Warum nicht eine "Punkt" -Klasse erstellen, die eine Von-Bis-Struktur implementiert?
"Bob wurde im Jahr 2000 geboren" ->
Sie können dann verschiedene Suchmethoden implementieren, indem Sie die Datumsangaben von bis eingeben. Das Fuzz-Attribut gibt einen nützlichen Hinweis darauf, wie genau das Datum ist, sodass Sie Fuzz == 1 für genaue Übereinstimmungen oder Fuzz == 31 für einen Monat oder so angeben können.
quelle