これは静的にチェックすることはできません。一般的なケースです。
次のスニペットを考えてみましょう:
d = datetime.strptime(read_date_from_network(), read_format_from_file())
このコードは完全に有効であり、両方read_date_from_network
とread_format_from_file
が本当に適切な形式の文字列を返すかどこ - または彼らは、総ごみ、返却なしまたは一部の両方かもしれうんざりそれにかかわらず、その情報はしか実行時に決定できないため、静的チェッカーは無力です。
多くはである何、datetime.strptimeの現在の定義を考えると、我々はは静的型付け言語を使用してたとしても、我々は(非常に特殊なケースを除いて)このエラーをキャッチすることができないであろう - 理由はことを、この関数の署名が開始から私たちを運命づけされている:両方文字列は、
classmethod datetime.strptime(date_string, format)
この定義では
、date_string
とformat
であっても、彼らactuallかかわらず、 yには特別な意味があります。私たちは、このような静的型付け言語で類似した何かを持っていた場合でも:
public DateTime strpTime(String dateString, String format)
コンパイラ(とリンターと皆を)まだだけ見ている:
public DateTime strpTime(String, String)
次のいずれも識別可能でないことを意味しています互いに:
strpTime("%B %d, %Y", "January 8, 2014") // strpTime(String, String) CHECK
strpTime("January 8, 2014", "%B %d, %Y") // strpTime(String, String) CHECK
strpTime("cat", "bat") // strpTime(String, String) CHECK
これで行うことができないと言っているわけではありませんすべて - Java/C++ /などのような静的型付けされた言語のためのいくつかのリンターが存在します。文字列リテラルをprintfなどの特定の関数に渡すと、その文字列リテラルを検査します。)、これはリテラル形式の文字列で直接その関数を呼び出すときにのみ行うことができます。私が提示した最初のケースでは、同じ文字列が無力になります。文字列が正しい形式であるかどうかはまだ分かっていないからです。リンターすなわち
はこれについて警告することができる場合があります
// Linter regex-es the first argument, sees %B et. al., warns you
strpTime("%B %d, %Y", "January 8, 2014")
が、このことについて警告することができません。
strpTime(scanner.readLine(), scanner.readLine())
は今、同じのpython内に操作することができ私は関数がファーストクラスなので非常に便利だとは思っていませんので、私は簡単に(仮説的なPythonの)リンターを書くことができます:
f = datetime.strptime
d = f("January 8, 2014", "%B %d, %Y")
そして、私たちは再びかなりくっついています。
ボーナス:ここ
問題何が悪かったのかはdatetime.strptime
は、これらの文字列のそれぞれへの暗黙的な意味を与えるということですが、それは型システムにその情報を表面化しません。可能なことは、2つの弦に異なるタイプを与えることでした。それで、使いやすさを犠牲にしてより安全性が向上しました。
例えば(使用PEP 484型注釈、a real thing!):
class DateString(str):
pass
class FormatString(str):
pass
class datetime(date):
...
def strptime(date_string: DateString, format: FormatString) -> datetime:
# etc. etc.
そして、それは一般的なケースでは良いリンティングを提供することが可能であることを開始する - DateStringのとformatStringのクラスが世話をする必要があるでしょうけれどもタイプ・システムはそのレベルで何もできないため、入力を検証する必要があります。
あとがき:
私はこれに対処するための最良の方法は、特定のDateTimeオブジェクトにバインドし、ちょうどフォーマット文字列を引数に取るさstrftime
方法を、使用して問題を回避することだと思います。これは、私たちがそれを抱きしめたときに私たちを切断しない関数シグネチャを与えることによって、問題全体を回避します。わーい。
alecxe通常、文字列をdatetimeに変換する場合は、strptime以外の特定の文字列に対してstrptime()を使用します。指定された文字列が適切なdatetime形式であるかどうかを調べるには、チェックするためにもっと多くの正規表現パターンが必要になります。 – MicroPyramid