Python:将类型提示与注释一起使用

Python: use Type Hints together with Annotations

在 Python 中,我们都知道 Type hints,它从 2015 年开始可用:

def greet(name: str) -> str:
    return "Hello, " + name

我们也知道 Function Annotations,特别是这里我指的是文本注释,例如:

def greet(name: "The name of the person to greet") -> str:
    return "Hello, " + name

但是是否可以将类型提示与文本函数注释一起使用

例如:

def greet(name: str, "The name of the person to greet") -> str:
    return "Hello, " + name

最后一个抛出错误。

我似乎无法在 PEP 或 Python 文档中找到关于这是否可能的任何来源。虽然我没有特别深入地搜索,但我仍然希望能提供潜在答案的来源。

由于注解可以是任何表达式(就 Python 解释器而言),从技术上讲,您可以使用元组作为注解:

def greet(name: (str, "The name of the person to greet")) -> str:
    return "Hello, " + name

它在函数的注释中的显示完全符合您的预期:

>>> greet.__annotations__
{'name': (<class 'str'>, 'The name of the person to greet'), 'return': <class 'str'>}

但是,如果您拥有了解其含义的工具,这只是 有用。据我所知,现有的静态类型检查器、linter、文档生成器等都无法识别作为类型和描述的元组的注释。

实际上,我建议只对 类型使用注释,因为这是绝大多数的标准用法,并使用注释或文档字符串来获取更多信息。

就像 Samwise 所说的那样,类型检查器不会理解注释是否是类型和描述(或您希望附加的任何其他元数据)的元组。 PEP 593 – Flexible function and variable annotations 通过以下方式解决这个问题:

from typing import Annotated

@dataclass
class Description:
    x: str

def greet(name: Annotated[str, Description("The name of the person to greet")]) -> str:
    return "Hello, " + name

我们引入包装器的原因 class Description 很明显,写入的字符串旨在成为我们使用的描述,因此其他分析注释的库不会混淆以防他们使用 str 作为自己的元数据。

然后,根据 typing.Annotated,您可以使用 typing.get_type_hints(name, include_extras=True) 在运行时获取描述。