代码之家  ›  专栏  ›  技术社区  ›  exhuma

“cast(…)”和“type:…”有什么区别?

  •  0
  • exhuma  · 技术社区  · 7 年前

    当在python中输入hinting时,我有两个选项可以将表达式标记为特定类型:

    from typing import cast
    
    foo = cast(str, expression)
    bar = expression  # type: str
    

    这两者有什么区别?

    我觉得有时候 cast 有效,但有时我不得不使用评论。但我还没有找到一个模式。不幸的是,我目前没有现成的代码示例,其中一个可以工作,但另一个不能工作。

    1 回复  |  直到 7 年前
        1
  •  1
  •   Michael0x2a    7 年前

    # type: ignore 意思是“请避免出现任何与类型相关的错误”。

    cast(TYPE, EXPR) 意思是“我知道你认为x的expr类型,但是我想让你假设这个类型实际上是type,好吗?”

    您通常使用 类型:忽略 当您遇到一些类型检查器的限制时,您将无法解决。例如,假设您尝试导入一些没有存根或类型定义的第三方库。在这种情况下,执行以下操作:

    # Results in errors like"
    # error: No library stub file for module 'library_with_no_hints'
    import library_with_no_hints
    

    …通常会导致错误。但你可以使用 类型:忽略 要消除该错误:

    import library_with_no_hints  # type: ignore
    

    您通常使用 cast 当您有额外的带外信息时,类型检查器不知道某些类型x实际上只是y。例如:

    def parse_config(assume_normalized: bool, thing: List[Union[int, str]]) -> List[int]:
        if assume_normalized:
            # The type-checker thinks that 'thing' is a List[Union[int, str]];
            # we now force it to assume it's really a List[int] instead.
            return cast(List[int], thing)
        else:
            output = []
            for item in thing:
                if isinstance(item, int):
                    output.append(item)
                else:
                    output.append(parse(item))
            return output
    

    您通常会看到强制转换,当a)您正在处理大量反序列化/序列化样式的代码,并且需要将广泛的类型强制转换为更具体的类型时,b)您正在使用多个继承执行奇怪的操作,或c)您的代码设计不好,并且已将自己漆成一个角落。

    我个人几乎从不使用强制转换——如果可以,我尽量避免使用强制转换,如果不可以,我至少会使用IsInstance检查和类似检查,因此如果我的假设最终出错,我的代码将在运行时崩溃。

    (我也试着忽略 类型:忽略 ,但它们有时会成为一种必要的邪恶/可以帮助您绕过类型检查器中的限制。)


    如果您计划在代码库中使用类型忽略或强制转换,那么还应该考虑配置类型检查器,这样当您在不必要的地方使用它们时,它会警告您。

    例如,使用mypy,您可以通过 --warn-unused-ignores --warn-unused-casts 旗帜。