我可以通知 mypy 表达式不会返回 Optional 吗?

问题描述

我有以下代码

def extract_table_date(bucket_path: str) -> str:
    event_date = re.search(r"date=([^/]+)",bucket_path)
    return event_date.group(1)[0:10].replace("-","")

mypy 在最后一行抛出错误

“Optional[Match[str]]”的“None”没有属性“group”

我想我可以通过为 event_date 分配一个类型来解决这个问题,而且我可以:

from typing import Match

def extract_table_date(bucket_path: str) -> str:
    event_date: Match = re.search(r"date=([^/]+)","")

但是 mypy 现在在函数的第一行抛出另一个错误

赋值中的类型不兼容(表达式类型为“Optional[Match[Any]]”,变量类型为“Match[Any]”)

我真的不知道如何通知 mypy 结果不是可选的,但我还是按照 Optional types and the None type 的建议添加一个断言:

from typing import Match

def extract_table_date(bucket_path: str) -> str:
    assert bucket_path is not None
    event_date: Match = re.search(r"date=([^/]+)","")

但 mypy 仍然引发相同的错误

我尝试通过更改为 event_date 定义的类型来修复:

from typing import Match,optional,Any

def extract_table_date(bucket_path: str) -> str:
    assert bucket_path is not None
    event_date: Optional[Match[Any]] = re.search(r"date=([^/]+)","")

但是(正如预期的那样)我现在又回到了几乎相同的原始错误

“Optional[Match[Any]]”的“None”没有属性“group”

关于如何解决这个问题有什么建议吗?

解决方法

Optionalevent_date,因为 re.search 不能保证返回匹配项。 mypy 警告您,如果是这种情况,这将引发 AttributeError。您可以通过执行 assert 来表示“不,我非常有信心不会出现这种情况”:

def extract_table_date(bucket_path: str) -> str:
    event_date = re.search(r"date=([^/]+)",bucket_path)
    assert event_date is not None
    return event_date.group(1)[0:10].replace("-","")

如果你错了,这段代码仍然会引发异常(AssertionError,因为你的 assert 会失败),但 mypy 将不再出错,因为 {{1 }} 在您访问其 event_date 属性时为 None

请注意,无需对 group 进行断言,因为它已显式键入为 bucket_path