是否可以创建正则表达式约束类型提示?

时间:2017-06-13 20:12:12

标签: python python-3.x type-hinting

我有一个帮助函数,可将%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)来完成吗?

2 个答案:

答案 0 :(得分:1)

使用类型提示在Python中什么也不做,并且作为静态检查器中类型的指示。它并不意味着执行任何操作,只是注释一种类型。

您无法进行任何验证,只需使用类型提示和检查器,即可确保传入的参数实际上是str类型。

答案 1 :(得分:1)

遗憾的是,目前无法使用类型静态验证字符串是否与精确格式匹配。这部分是因为在编译时检查给定变量可以容纳的确切值是非常难以实现的(实际上,在某些情况下是NP难的),部分是因为面对诸如用户输入之类的问题,问题变得不可能。因此,如果有的话,不太可能在不久的将来将此功能添加到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在编译时。然后,您需要设计程序,以最大限度地减少调用这些函数的频率,以避免产生不必要的开销,但希望这样做不会太费力。