如何进行类型注释类型断言?
How to make type-annotation-only type assertions?
我有两个功能:
def get_foo(params) -> Optional[str]
def bar(foo: str)
以及将这些函数链接在一起的函数:
def f(params):
# other stuff up here
foo = get_foo(params)
return bar(foo)
根据函数中发生的其他事情,我知道 get_foo
的结果 永远不会 是 None。
当我运行mypy
反对这个文件时,我当然会得到错误:
error: Argument 1 of "bar" has incompatible type "Optional[str]"; expected "str"
有道理。
我可以添加一个 assert foo is not None
语句,但这是热路径代码,在我的测试中它具有可衡量的性能影响。 我只想为 mypy 做一个类型断言。我该怎么做?
编辑:我也尝试在赋值语句后添加注释#type: str
,但这产生了类似的错误
你不会对此感到高兴的。官方设计的向静态类型检查器断言值具有特定类型的方法是 typing.cast
,这是一个具有实际 运行 时间成本的实际函数,我相信 more 比您要更换的 assert
贵。它只是 returns 它的第二个参数没有改变,但它仍然有函数调用开销。 Python 的类型注释系统不是用零开销类型断言语法设计的。
作为替代方案,您可以使用 Any
作为“逃生通道”。如果您使用类型 Any
注释 foo
,mypy 应该允许 bar
调用。局部变量注释没有 运行 时间成本,因此唯一的 运行 时间成本是额外的局部变量存储和查找:
from typing import Any
def f(params):
foo: Any = get_foo(params)
return bar(foo)
除此之外,您最好的选择可能是使用 assert
和 运行 Python 以及 -O
标志,这会禁用断言。
您可以使用 TYPE_CHECKING
变量,该变量在运行时为 False
,但在类型检查期间为 True
。这将避免 assert
:
的性能损失
from typing import TYPE_CHECKING
def f(params):
# other stuff up here
foo = get_foo(params)
if TYPE_CHECKING:
assert foo is not None
return bar(foo)
我有两个功能:
def get_foo(params) -> Optional[str]
def bar(foo: str)
以及将这些函数链接在一起的函数:
def f(params):
# other stuff up here
foo = get_foo(params)
return bar(foo)
根据函数中发生的其他事情,我知道 get_foo
的结果 永远不会 是 None。
当我运行mypy
反对这个文件时,我当然会得到错误:
error: Argument 1 of "bar" has incompatible type "Optional[str]"; expected "str"
有道理。
我可以添加一个 assert foo is not None
语句,但这是热路径代码,在我的测试中它具有可衡量的性能影响。 我只想为 mypy 做一个类型断言。我该怎么做?
编辑:我也尝试在赋值语句后添加注释#type: str
,但这产生了类似的错误
你不会对此感到高兴的。官方设计的向静态类型检查器断言值具有特定类型的方法是 typing.cast
,这是一个具有实际 运行 时间成本的实际函数,我相信 more 比您要更换的 assert
贵。它只是 returns 它的第二个参数没有改变,但它仍然有函数调用开销。 Python 的类型注释系统不是用零开销类型断言语法设计的。
作为替代方案,您可以使用 Any
作为“逃生通道”。如果您使用类型 Any
注释 foo
,mypy 应该允许 bar
调用。局部变量注释没有 运行 时间成本,因此唯一的 运行 时间成本是额外的局部变量存储和查找:
from typing import Any
def f(params):
foo: Any = get_foo(params)
return bar(foo)
除此之外,您最好的选择可能是使用 assert
和 运行 Python 以及 -O
标志,这会禁用断言。
您可以使用 TYPE_CHECKING
变量,该变量在运行时为 False
,但在类型检查期间为 True
。这将避免 assert
:
from typing import TYPE_CHECKING
def f(params):
# other stuff up here
foo = get_foo(params)
if TYPE_CHECKING:
assert foo is not None
return bar(foo)