Überschreibe Operator +, um in Python Datum + Zeit = Datum zu setzen

7

Ich habe ein paar Klassen, die eingebaute Datetime erweitern. *

Gibt es einen guten Grund, + ( MyTime.__radd___ ) nicht zu überladen, damit MyDate + MyTime MyDateTime zurückgibt?

    
Paulo Scardine 08.11.2010, 20:33
quelle

6 Antworten

12

Das wäre im Allgemeinen verpönt, weil Sie wirklich kombinieren statt hinzufügen; Aus diesem Grund verfügt die aktuelle Datetime-Bibliothek über eine Kombinationsmethode , anstatt die Addition auf diese Weise zu verwenden .

Mir sind keine anderen Fälle in Python bekannt, wo <instance of TypeA> + <instance of TypeB> <instance of TypeC> erzeugt. Das Prinzip der geringsten Verwunderung legt nahe, dass Sie einfach eine combine -Methode anstelle einer Überladungs-Addition angeben sollten.

>     
Eli Courtwright 08.11.2010, 20:37
quelle
16

Dies ist bereits als Klassenmethode implementiert, datetime.datetime.combine :

%Vor%

druckt

%Vor%     
nosklo 08.11.2010 20:42
quelle
4

Ja, es gibt mindestens einen guten Grund, dies nicht zu tun: Die resultierende Instanz unterscheidet sich vollständig von den beiden Eingabe-Instanzen. Ist das wichtig? Ich denke nicht - bedenkt, dass date - date ergibt timedelta .

So wie ich es sehe:

  • Ist es sinnvoll, zwei Daten hinzuzufügen? Nein.
  • Macht es Sinn, zwei Mal zusammen zu addieren? Nein.
  • Ist es sinnvoll, ein Datum und eine Uhrzeit hinzuzufügen? Yup!
  • Ist das Hinzufügen eines Datums und eines Timedeltas sinnvoll? Vielleicht.
  • Ist es sinnvoll, eine Zeit und ein Timedelta hinzuzufügen? Vielleicht.

und für die Subtraktion

  • Macht es Sinn, zwei Daten zu subtrahieren? Ja.
  • Macht das Subtrahieren von zwei Malen Sinn? Ja.
  • Ist das Subtrahieren einer Zeit von einem Datum sinnvoll? Nein.
  • Ist das Subtrahieren eines Timedelta von einem Datum sinnvoll? Vielleicht.
  • Ist das Subtrahieren eines Zeit-Deltas von einer Zeit sinnvoll? Vielleicht.

Entwicklung nach dem Sinnvollen:

%Vor%

Wenn ich also ein Date-, Time-, DateTime- und TimeDelta-Framework entwarf, würde ich Folgendes erlauben:

%Vor%

und für diese:

%Vor%

Ich würde standardmäßig den gleichen Typ zurückgeben, wenn das Timedelta keinen anderen Typ hätte, und eine Ausnahme auslösen, wenn das Timedelta einen anderen Typ hätte, aber es würde eine Einstellung geben, die das steuert. Das andere mögliche Verhalten wäre, den nicht benötigten Teil fallen zu lassen - so würde ein Datum, kombiniert mit einem Zeitdelta, das Stunden hatte, die Stunden fallen lassen und ein Datum zurückgeben.

    
Ethan Furman 07.01.2012 06:04
quelle
1

Aufgrund der Existenz der Additions- und Subtraktionsoperatoren Datum, Zeit und Datum / Uhrzeit würde ich denken, dass dies in Ordnung ist, solange es gut definiert ist.

Derzeit (2.7.2):

%Vor%

Ich glaube, das Folgende ist auch für eine Erweiterung sinnvoll:

%Vor%

Ich würde auch folgendes vorschlagen, aber time hat sehr spezifische Min- und Max-Werte für hour , minute , second und microsecond , was einen stillen Umlauf von Werten oder erfordert Rückgabe eines anderen Typs:

%Vor%

Ebenso kann date nicht mit timedelta umgehen, wenn weniger als ein Tag hinzugefügt wird. Oft wurde mir gesagt, dass ich Duck Typing mit Python verwenden sollte, weil das die Absicht ist. Wenn das wahr ist , würde ich die folgende fertige Schnittstelle vorschlagen:

%Vor%

In dem Fall, dass date Präzisionsverlust hat (für timedelta mit partiellen Tagen), wird es zu datetime hochgestuft. Ähnlich verhält es sich mit dem Fall, dass time einen Präzisionsverlust hat (für timedelta , die ein Ergebnis von mehr als einem Tag oder eine negative Zeit ergeben), wird es zu timedelta hochgestuft. Allerdings bin ich nicht ganz mit [time|timedelta] zufrieden. Es macht Sinn, wenn man den Rest der Schnittstelle von Parallelitäts- und Präzisionsansichten verwendet, aber ich denke, es könnte eleganter sein, die Zeit einfach in die richtige Stunde zu bringen und so alle [time|timedelta] auf einfach time zu setzen, aber Das lässt uns leider mit verlorener Präzision zurück.

    
Mark Ribau 12.01.2012 04:18
quelle
1

Meiner Meinung nach sind die wertvollsten Nutzungsmöglichkeiten für das Überladen von Operatoren Situationen, in denen viele Eingabewerte kombiniert werden können. Du würdest dich nie damit befassen wollen:

%Vor%

oder

%Vor%

Wir überladen also mathematische Symbole, um eine intuitivere Syntax zu erzeugen. Eine andere Möglichkeit, dieses Problem zu lösen, sind variadische Funktionen wie + in Scheme.

Mit date + time = datetime ist es nicht sinnvoll, datetime + datetime , datetime + time oder datetime + date hinzuzufügen, damit Sie nie auf eine Situation wie die oben genannten stoßen können.

Meiner Meinung nach ist es wieder richtig, eine Konstruktormethode zu verwenden. In einer Sprache mit starker Schreibweise wie C ++ hätten Sie DateTime(const Date &d, const Time &t) . Mit Pythons dynamischer Typisierung habe ich der Funktion einen Namen gegeben, datetime.combine(date, time) , um den Code klarer zu machen, wenn die Typen der Eingabevariablen im Code nicht sichtbar sind.

    
japreiss 12.01.2012 22:39
quelle
0

Ich denke, die wichtigsten Dinge sind Funktionalität und Effizienz. Natürlich ist die Verwendung eines einfachen + Operators einfacher zu verwenden, aber ich bin mir nicht sicher über die Funktionalität.

Wenn wir es mit datetime.combine vergleichen, dann ist Was combine do:

%Vor%

Für dtm

  • Wenn dt ein Datumsobjekt und tm ein Zeitobjekt ist, dann werden Datum Informationen aus dt , Zeit Info und übernommen tzinfo stammt von tm object
  • Wenn dt ein datetime Objekt ist, dann werden seine time und tzinfo Attribute ignoriert.

Von diesem Standpunkt aus scheint die Arbeit mit datetime -Objekten keine einfachen Objekte zu sein, sondern mehr komplexe Strukturen mit verschiedenen Attributen, wie timezone info .

Wahrscheinlich deshalb haben datetime Objekte einige zusätzliche Funktionen, die für die Formatierung des Objekttyps und der Datenstruktur des Objekts verwendet werden.

Python haben ein Motto (so etwas):

  

In Python ist nichts änderbar, wenn Sie wissen, was Sie tun. Wenn nicht, ist es besser, die Bibliotheksfunktionen so zu belassen, wie sie sind ...

Meiner Meinung nach ist es besser, combine zu verwenden, um + operator

zu überladen     
FallenAngel 11.01.2012 17:14
quelle

Tags und Links