Io sostengo che questo non può essere controllato staticamente nel caso generale.
Si consideri il seguente frammento di codice:
d = datetime.strptime(read_date_from_network(), read_format_from_file())
Questo codice può essere completamente valida, dove entrambi read_date_from_network
e read_format_from_file
davvero corde del formato corretto tornare - o possono essere spazzatura totale, sia di ritorno Nessuno o un po ' una schifezza. Indipendentemente da ciò, tale informazione può solo essere determinata in fase di esecuzione - quindi, un controllo statico è impotente.
Cosa c'è di più, dato l'attuale definizione di datetime.strptime, anche se siamo stati utilizzando un linguaggio a tipizzazione statica, non saremmo in grado di catturare questo errore (tranne in casi molto specifici) - il motivo è che la firma di questa funzione ci ha condannata fin dall'inizio:
classmethod datetime.strptime(date_string, format)
in questa definizione, date_string
e format
sono entrambi stringhe, anche se actuall hai un significato speciale Anche se avessimo qualcosa di analogo in un linguaggio a tipizzazione statica come questo:
public DateTime strpTime(String dateString, String format)
Il compilatore (e linter e tutti gli altri) ancora vede solo:
public DateTime strpTime(String, String)
Il che significa che nessuno dei seguenti sono distinguibili gli uni dagli altri:
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
Questo non vuol dire che non può essere fatto a tutti - esistono alcuni linters per linguaggi tipizzati staticamente come Java/C++/etc. che controllerà i letterali stringa quando li passi ad alcune funzioni specifiche (come printf, ecc.), ma questo può essere fatto solo quando si chiama quella funzione direttamente con una stringa di formato letterale. Gli stessi ltri diventano impotenti nel primo caso che ho presentato, perché semplicemente non è ancora noto se le stringhe saranno nel formato giusto.
cioè A linter possono essere in grado di mettere in guardia su questo:
// Linter regex-es the first argument, sees %B et. al., warns you
strpTime("%B %d, %Y", "January 8, 2014")
ma non sarebbe in grado di mettere in guardia su questo:
strpTime(scanner.readLine(), scanner.readLine())
Ora, lo stesso potrebbe essere progettato in un pitone linter, ma non credo che sarebbe molto utile perché le funzioni sono di prima classe, quindi potrei facilmente sconfiggere il lintero (ipotetico pitone) scrivendo:
f = datetime.strptime
d = f("January 8, 2014", "%B %d, %Y")
E poi siamo di nuovo in crisi.
Bonus: What Went Wrong
Il problema qui è che il datetime.strptime
dà significato implicito di ciascuna di queste stringhe, ma non superficiale che informazioni al sistema tipo. Quello che si sarebbe potuto fare era dare alle due stringhe tipi diversi, quindi ci sarebbe stata maggiore sicurezza, anche se a scapito di una certa facilità d'uso.
esempio (usando PEP 484 annotazioni di tipo, a real thing!):
class DateString(str):
pass
class FormatString(str):
pass
class datetime(date):
...
def strptime(date_string: DateString, format: FormatString) -> datetime:
# etc. etc.
Poi avrebbe cominciato a essere possibile fornire una buona linting nel caso generale - anche se il DateString e classi FormatString avrebbero bisogno di prendersi cura di convalidare il loro input, perché ancora una volta, il sistema di tipi non può fare nulla a quel livello.
Postfazione:
Credo che il modo migliore per affrontare questo è di evitare il problema utilizzando il metodo strftime
, che è legato a un oggetto datetime specifico e richiede solo un argomento stringa di formato. Ciò aggira l'intero problema dandoci una firma di funzione che non ci taglia quando la abbracciamo. Sìì.
alecxe, in genere se vogliamo convertire una stringa in data/ora usiamo strptime() su una stringa particolare, a parte strptime possiamo controllare la stringa con espressioni regolari se la stringa data è in formato datetime appropriato o meno, ma prenderebbe modelli di espressioni più regolari da controllare. – MicroPyramid