Mischen von datetime.strptime () - Argumenten

8

Es ist ein häufiger Fehler, die datetime.strptime() zu verwechseln format string und date string Argumente mit:

%Vor%

statt umgekehrt:

%Vor%

Natürlich würde es während der Laufzeit scheitern:

%Vor%

Aber ist es möglich, dieses Problem statisch schon vor der tatsächlichen Ausführung des Codes zu erfassen? Ist es etwas pylint oder flake8 kann helfen?

Ich habe die PyCharm-Code-Überprüfung versucht, aber beide Snippets geben keine Warnungen aus. Wahrscheinlich, weil beide Argumente den gleichen Typ haben - beide sind Strings, die das Problem erschweren. Wir müssten tatsächlich analysieren, ob eine Zeichenfolge eine Datumsformat-Zeichenfolge ist oder nicht. Auch die Sprachinjektionen PyCharm / IDEA-Funktion sieht relevant aus.

    
alecxe 01.07.2016, 14:26
quelle

1 Antwort

18

Ich behaupte, dass dies im allgemeinen Fall nicht statisch überprüft werden kann .

Betrachten Sie das folgende Snippet:

%Vor%

Dieser Code kann vollständig gültig sein, wobei sowohl read_date_from_network als auch read_format_from_file wirklich Zeichenfolgen des richtigen Formats zurückgeben - oder sie können totaler Müll sein, beide kehren None oder irgendeinen Mist zurück. Unabhängig davon kann diese Information nur zur Laufzeit festgelegt werden - daher ist ein statischer Checker nicht machtlos.

Darüber hinaus konnten wir diesen Fehler (abgesehen von sehr spezifischen Fällen) nicht erfassen, selbst wenn wir mit einer statisch typisierten Sprache verwenden würden. Der Grund dafür ist, dass die Signatur dieser Funktion uns von Anfang an zum Untergang verführt hat :

%Vor%

In dieser Definition sind date_string und format beide Zeichenfolgen , obwohl sie tatsächlich eine besondere Bedeutung haben. Selbst wenn wir in einer statisch typisierten Sprache etwas Ähnliches hätten:

%Vor%

Der Compiler (und linter und alle anderen) sieht immer noch nur:

%Vor%

Was bedeutet, dass keine der folgenden voneinander unterscheidbar ist:

%Vor%

Das soll nicht heißen, dass es überhaupt nicht möglich ist - es gibt einige Linters für statisch typisierte Sprachen wie Java / C ++ / etc. Dadurch werden Zeichenfolgenliterale überprüft, wenn Sie sie an bestimmte Funktionen (z. B. printf usw.) übergeben. Dies kann jedoch nur erfolgen, wenn Sie diese Funktion direkt mit einer literalen Formatzeichenfolge aufrufen. Die gleichen Linters werden im ersten Fall, den ich vorgestellt habe, genauso hilflos, weil es noch nicht bekannt ist, ob die Strings das richtige Format haben.

d. Ein linster kann davor warnen:

%Vor%

aber es wäre nicht in der Lage davor zu warnen:

%Vor%

Nun könnte das Gleiche in einen Python-Linter eingearbeitet werden, aber ich glaube nicht, dass es sehr nützlich wäre, weil Funktionen erstklassig sind, so dass ich den (hypothetischen Python) Linter leicht durch Schreiben besiegen könnte:

%Vor%

Und dann sind wir wieder ziemlich abgespritzt.

Bonus: Was falsch ging

Das Problem hierbei ist, dass datetime.strptime jeder dieser Zeichenfolgen eine implizite Bedeutung gibt, aber diese Information nicht dem Typsystem zur Verfügung stellt. Was hätte getan werden können, um den beiden Strings unterschiedliche Typen zu geben - dann hätte es mehr Sicherheit geben können, wenn auch auf Kosten einer gewissen Benutzerfreundlichkeit.

z. B. (unter Verwendung von Anmerkungen vom Typ PEP 484, eine echte Sache! ):

%Vor%

Dann würde es im Allgemeinen möglich sein, gutes Linting bereitzustellen - obwohl die DateString- und FormatString-Klassen ihre Eingaben überprüfen müssten, da das Typsystem wiederum auf dieser Ebene nichts tun kann .

Nachwort:

Ich denke, der beste Weg, damit umzugehen, besteht darin, das Problem zu vermeiden, indem Sie verwenden strftime Methode, die an ein bestimmtes datetime-Objekt gebunden ist und nur ein Formatstring-Argument verwendet. Das umgeht das ganze Problem, indem es uns eine Funktionssignatur gibt, die uns nicht schneidet, wenn wir sie umarmen. Yay.

    
Dan 06.07.2016, 01:51
quelle