Python中类级别的类型提示的意义是什么?

ldioqlga  于 2023-05-08  发布在  Python
关注(0)|答案(1)|浏览(87)

我试图理解类类型提示的意义。我知道我们可以在类的__init__方法中使用类型提示,如下所示:

class Foo:
    def __init__(self, x: int):
        self.x = x

然而,我遇到了另一种在类级别定义类型提示的方法,如下面的示例所示:

class Bar:
    x : int
    def __init__(self, x: int):
        self.x = x

像这样使用类级别的类型提示的目的是什么?与只在__init__方法中使用类型提示相比,它们是否提供了任何额外的好处或信息?

eivgtgni

eivgtgni1#

  • “class-level type hints”*,尽管出现在你通常会看到类属性的地方,显式地指定了 instance 属性的预期类型(除了使用ClassVar的地方)。如PEP-526所述:

类和示例变量标注

类型注解还可以用于注解类主体和方法中的类和示例变量。特别是,无值表示法a: int允许注解应该在__init____new__中初始化的示例变量。建议的语法如下:

class BasicStarship:
    captain: str = 'Picard'               # instance variable with default
    damage: int                           # instance variable without default
    stats: ClassVar[Dict[str, int]] = {}  # class variable

这里ClassVar是一个由类型模块定义的特殊类,它向静态类型检查器指示不应在示例上设置此变量。
你为什么要用它们?
在第一个示例中:

class Foo:
    def __init__(self, x: int):
        self.x = x

__init__的 * 参数 * 具有类型提示,防止例如Foo(123),但 * 属性 * Foo("bar").x的类型必须从__init__中的赋值self.x = x推断
相比之下,在第二个示例中:

class Bar:
    x : int
    def __init__(self, x: int):
        self.x = x

你有一个self.x类型的显式定义,所以赋值实际上可以通过例如MyPy
为什么有用?
给类型系统更多的信息可以让它更精确地帮助你。例如,如果您随后 * 更改了 * 参数类型:

class Bar:
    x: int
    def __init__(self, x: str):
                        # ^~~
        self.x = x

而不是在some_bar.x被 * 访问 * 的代码库中到处都是错误,假设它是一个int(就像你在属性的类型被推断的情况下一样),你会得到一个错误,直接指向它被 * 分配 * 的地方,并确切地知道在哪里修复它:

class Bar:
    x: int
    def __init__(self, x: str):
        self.x = int(x)

不过,请记住(根据the docs):

注意Python运行时不强制函数和变量类型注解。它们可以被第三方工具使用,如类型检查器、IDE、链接器等。

Python本身不会在这方面出错,你需要像MyPy这样的工具来充分利用注解。

相关问题