首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >类型类型的类型断言

类型类型的类型断言
EN

Stack Overflow用户
提问于 2021-07-27 07:19:31
回答 2查看 1.2K关注 0票数 2

在Python中,我们可以以这种方式将一个类型分配给一个变量,并传递mypy的类型:

代码语言:javascript
复制
from typing import Type, Union


class Foo:
    pass


MyType: Type[Foo] = Foo

类似地,我们也可以使用Union来键入

代码语言:javascript
复制
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给出了以下代码示例的错误:

代码语言:javascript
复制
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")

castisinstance也不起作用。

代码语言:javascript
复制
MyType = func(True)
cast(Type[Bar], MyType)
Test: Bar = MyType  # MyType is considered `Type[Bar] | Type[Foo]`
代码语言:javascript
复制
MyType = func(True)
assert isintance(MyType, Type[Bar])
Test: Bar = MyType  # MyType is considered `Type[Bar] | Type[Foo]`

我的问题是:如何对类型类型进行类型缩小?还是类型限制?如果是这样的话,解决办法是什么?

相关信息:

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-07-27 08:05:44

cast助手返回其受约束的参数,实际上它不会将其参数更改为受约束。

cast分配到所需的Type[...]并分配或使用结果:

代码语言:javascript
复制
Test = cast(Type[Bar], MyType)
reveal_type(Test)  # note: Revealed type is "Type[so_testbed.Bar]"
票数 3
EN

Stack Overflow用户

发布于 2021-07-27 23:24:06

另一种避免使用typing.castisinstance的解决方案是使用typing.overload,它允许您注册单个函数的多个签名。在运行时,所有使用@typing.overload修饰的函数都会被忽略,而倾向于“具体”实现,因此这些函数的主体可以是文字省略。通过将typing.overloadtyping.Literal相结合,如果传入值True,则可以注册函数的一个签名,如果传入值False,则可以注册另一个签名:

代码语言:javascript
复制
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)()

它的类型-检查罚款。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68540528

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档