2017-06-13 36 views
0

我有一個轉換%Y-%m-%d %H:%M:%S - 格式化字符串到datetime.datetime一個輔助功能:是否可以創建一個正則表達式約束類型的提示?

def ymdt_to_datetime(ymdt: str) -> datetime.datetime: 
    return datetime.datetime.strptime(ymdt, '%Y-%m-%d %H:%M:%S') 

我可以驗證的功能本身ymdt格式,但它會是更加有用的自定義對象使用作爲類型暗示的論點,類似

from typing import NewType, Pattern 

ymdt_pattern = '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9]' 
YmdString = NewType('YmdString', Pattern[ymdt_pattern]) 

def ymdt_to_datetime(ymdt: YmdString)... 

我是否會錯誤的兔子洞?這應該是mypy還是某個地方的問題?或者可以用當前的類型提示實現(3.61)來完成嗎?

回答

1

使用類型提示在Python中不做任何事情,並且充當靜態檢查器中類型的指示。這並不意味着要執行任何操作,只是註釋一種類型。

你不能做任何驗證,你只能使用類型提示和檢查器進行驗證,確保傳入的參數實際上是str類型。

+0

謝謝,吉姆。我不想執行任何操作,只是想知道我是否可以自定義類型(一種特殊格式的「str」),以便檢查器檢查。 –

+1

@ZevAverbach我明白了。不,你不能檢查一個字符串的外觀,你只能檢查它的類型。所做的檢查基於類型,因此無論「str」對象如何,它仍然是一個「str」對象。 –

1

不幸的是,目前沒有辦法讓類型靜態地驗證您的字符串是否匹配精確的格式。這部分是因爲在編譯時檢查一個給定變量所能容納的確切值是非常難以實現的(事實上,在某些情況下是NP-hard),部分原因是因爲在用戶輸入等問題面前,問題變得不可能。因此,不久的將來,這個功能不太可能會被添加到mypy或Python打字生態系統中。

一個潛在的解決方法是利用NewType,並仔細控制何時構建該格式的字符串。也就是說,你可以這樣做:

from typing import NewType 
YmdString = NewType('YmdString', str) 

def datetime_to_ymd(d: datetime) -> YmdString: 
    # Do conversion here 
    return YmdStr(s) 

def verify_is_ymd(s: str) -> YmdString: 
    # Runtime validation checks here 
    return YmdString(s) 

如果你只使用這樣的功能介紹YmdString類型的值,做測試,以確認您的「構造函數」是完美的工作,你可以與更多或更少的安全區分字符串和YmdString在編譯時。然後你會想要設計你的程序來最大限度地減少你調用這些函數的頻率,以避免產生不必要的開銷,但是希望這樣做不會太繁重。

+0

謝謝,@Michael。你是不是故意在'datetime_to_ymd'的某個地方調用'verify_is_ymd'或者我錯過了你的觀點? –

+1

@ZevAverbach - 你可以,但這不是必須的。如果仔細測試'datetime_to_ymd'到你高度自信的地步,那麼你可以完全省略運行時檢查。 (也就是說,不是通過類型系統或運行時檢查對'datetime_to_ymd'產生信心,而是通過單元測試獲得信心。相反,你的其他代碼會調用這兩個函數中的一個(或者你寫的其他'構造函數')。當然,如果單元測試不足以說服你的正確性,那麼你可以在'datetime_to_ymd'內調用驗證函數。 – Michael0x2a

相關問題