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

Zev*_*ach 4 python type-hinting python-3.x

我有一个辅助函数,可以将一个%Y-%m-%d %H:%M:%S-formatted 字符串转换为一个datetime.datetime

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

我可以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)...
Run Code Online (Sandbox Code Playgroud)

我是不是走错了兔子洞?这应该是mypy某个地方或某个地方的问题吗?或者这可以通过当前的类型提示实现(3.61)来完成吗?

Mic*_*x2a 5

不幸的是,目前没有办法静态验证您的字符串是否与精确格式匹配。这部分是因为在编译时检查给定变量可以保存的确切值非常难以实现(实际上,在某些情况下是 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)
Run Code Online (Sandbox Code Playgroud)

如果您仅使用此类函数来引入类型值YmdString并进行测试以确认您的“构造函数”工作正常,则您或多或少可以YmdString在编译时安全地区分字符串。然后您希望设计您的程序以最小化您调用这些函数的频率以避免产生不必要的开销,但希望这样做不会太繁重。


Jim*_*ard 1

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

您无法进行任何验证,您所能做的就是使用类型提示和检查器来确保传入的参数实际上是类型str