在Python中,我们可以以这种方式将一个类型分配给一个变量,并传递mypy的类型:
from typing import Type, Union
class Foo:
pass
MyType: Type[Foo] = Foo类似地,我们也可以使用Union来键入
from typing import Type, Union
class Foo:
pass
class Bar:
pass
def func(is_bar: bool) -> Union[Type[Foo], Type[Bar]]:
if is_bar:
return Bar
else:
return Foo了解is_bar的值,在调用func进行类型缩小之后使用断言是完全合理的。
但是,断言似乎根本不适用于MyType,因为mypy给出了以下代码示例的错误:
MyType = func(True)
assert MyType is Bar
# `assert MyType is Type[Bar]` gives the same result
Test: Bar = MyType # Incompatible types in assignment (expression
# has type "Union[Type[Foo], Type[Bar]]",
# variable has type "Bar")cast和isinstance也不起作用。
MyType = func(True)
cast(Type[Bar], MyType)
Test: Bar = MyType # MyType is considered `Type[Bar] | Type[Foo]`MyType = func(True)
assert isintance(MyType, Type[Bar])
Test: Bar = MyType # MyType is considered `Type[Bar] | Type[Foo]`我的问题是:如何对类型类型进行类型缩小?还是类型限制?如果是这样的话,解决办法是什么?
相关信息:
发布于 2021-07-27 08:05:44
cast助手返回其受约束的参数,实际上它不会将其参数更改为受约束。
将cast分配到所需的Type[...]并分配或使用结果:
Test = cast(Type[Bar], MyType)
reveal_type(Test) # note: Revealed type is "Type[so_testbed.Bar]"发布于 2021-07-27 23:24:06
另一种避免使用typing.cast或isinstance的解决方案是使用typing.overload,它允许您注册单个函数的多个签名。在运行时,所有使用@typing.overload修饰的函数都会被忽略,而倾向于“具体”实现,因此这些函数的主体可以是文字省略。通过将typing.overload与typing.Literal相结合,如果传入值True,则可以注册函数的一个签名,如果传入值False,则可以注册另一个签名:
from typing import Type, Union, overload, Literal
class Foo:
pass
class Bar:
pass
@overload
def func(is_bar: Literal[True]) -> Type[Bar]: ...
@overload
def func(is_bar: Literal[False]) -> Type[Foo]: ...
def func(is_bar: bool) -> Union[Type[Foo], Type[Bar]]:
if is_bar:
return Bar
else:
return Foo
test: Type[Bar] = func(True)
test2: Type[Foo] = func(False)
test3: Bar = func(True)()
test4: Foo = func(False)()它的类型-检查罚款。
https://stackoverflow.com/questions/68540528
复制相似问题