我想要一只新鸭子

2021-03-19 03:48:22

Mypy是Python的静态类型检查器。如果你是不是熟悉,你应该看看;它正在迅速成为标准的FORPETHON项目。所有时尚的年轻人都这样做。用yypy,您可以获得快速实验的高级动态类型的所有好处,以及严格类型的所有好处检查您的测试并提高可靠性。 1世界上最好的!

Mypy可以改变您编写Python代码的方式。在大多数情况下,这是为了铁膜。例如,我已经在大量的情况下找到了无论没有人如何糟糕。但这可以显着改变y ypy。现在,当你返回没有时,你可以说 - >可选[str]和最轻松的是,您的所有呼叫者都会快速,静态检查到它们可能会在其中遇到的位置,而不是遇到的属性错误,这将这是一个比冒险培养运行时异常更具吸引力的选项(哪种mypy无法检查)。

但在某些情况下,在某些情况下,在添加类型的注释时,它们可以使您的代码更大,特别是如果您用最初最初的类型的类型注释。要说,您定义了一些自定义类,然后说Parameters与返回值您的函数和方法是您刚刚定义的那些类的函数。

大多数Mypy教程为您提供了一堆与str,int,列表[int],也许是可选的[float]或两个,然后在定义自己的课程时留给您的所有文档;然而,巨大的世界应用程序是定制课程。

所以,如果你是mypy的新手,特别是如果你将它申请到一个大量的代码库,那么写一个小号代码是非常自然的:

来自Dataclasses导入DataClass @DataClass类鸭子:安静:Bool =假Def Quack(Self) - >无:打印(" Quack。"如果是自我。安静的别的"嘎嘎!")

def duck_war(侵略者:鸭,后卫:鸭子) - >没有:侵略者。 Quack()防御者。 Quack()打印("唯一的胜利举动不玩。")

在没有型号的,Pre-mypy python,除了是关于升级暴力的倾向的消息之外,duck_war是一个非常灵活的功能,无论它定义如何。它可以采用Quack()方法。

但是,虽然Mypy Type-Check的严格性带来了一定程度的安全性 - 但没有没有意外地伪装成鸭子的鸭子 - 它也增加了脆性的级别。使用仔细构造的假装的测试现在将失败坦白检查,因为Duck_war技术上是仅靠鸭子的精确诉讼而不是别的。

所以当你想要别的行为略有不同的东西时 - 当你是一个新的鸭子2,所以说话 - 你做什么?

有几种反形你可以到达这个Asyou开始你的Mypy旅程:

添加#类型:忽略所有测试的注释,或删除其类型的签名,以便他们没有得到类型。这种解决方案用浴水抛出婴儿,因为它消除了任何这些呼叫者经验的任何安全性。

为您所知的任何东西添加到施放(鸭子,......)的呼叫为您的目的为“足够”。这更细粒度和目标(并且可以是一个很好的黑客,用于与提供过于特定的类型存根的图书馆,但这也会逐渐交流安全,因为在演员的角度来看,任何东西都没有验证任何东西除非您构建您自己的Ad-hoc系统,否则请执行此操作。

鸭鸭。这也可能是有利的,如果必须的话也不会太糟糕; Mypy从Python继承中删除了一些最尖锐的边缘,在覆盖方法附近提供一些保护导轨,但由于所有通常的原因,它仍然是一个错误的想法。

Mypy有一个功能,键入.protocol,它提供了一种简单的方法来描述具有Quack()方法的任何对象。

现在,只有一个小修改它的签名 - 同时留下图像 - Duck_war现在可以支持任何足够的东西:

除了使它成为其他代码之外 - 例如,单位测试 - 在没有子类化车的情况下将自己的Ducky实施传递到Duck_war,这种变化也提高了Duck_war实现本身的安全性。以前,当鸭子拿下鸭子时,它适用于Duck_war以访问.quiet属性,因为它是访问的.quet .quet是一个内部实施细节。

现在,我们可以添加一个下划线前缀来安静地使它“私有”,但似乎仍然可以愉快地让您访问它。因此,协议允许您清楚地揭示您对您希望参数所在的类型的意图。

不幸的是,键入.protocol将其生命始于键入_extensions.protocol:最初在Mypy中不存在的类型系统的自定义扩展功能,而不是在标准库中直到3.8。像易于易于和序列一样的内置类型是通过略微特别的y ypy略微特别的类型检查的asif,但它仍然对休闲用户来说尚不清楚这是如何发生这种情况。

然而,其他类型,如io.textio,不要这么行动,而且为mypy的可见程序项目具有太严格或无法修饰的类型,因为它们达到了这一点。

所以我真的想写这篇文章来突出显示的抄写类型的协议样式,并鼓励人们使用它。

我描述的概念在类型理论的世界中并不新鲜。

用大多数类型 - 内置,自定义类和抽象基类在Mypy中键入工作的方式 - 被称为名称分类。标称为“基于名称”;如果您已直接引用它的名称,它会将其与它的实例相比,然后它匹配。

换句话说:如果它被命名为“鸭子”,这是一只鸭子。有一些AdvanageSto标称键入3,但这种脆性不是很有粘土的!

相反,协议所完成的类型检查的类型称为结构键入。 4呼叫者匹配协议的黑色取决于yourobject的结构 - 换句话说,它具有哪些方法和属性。

甚至是其他 - 如果它是.quack()喜欢鸭子,它是一只鸭子。

如果您刚刚开始使用MyPy - 特别是如果您正在构建一个图书馆,则导出用户预期的类型 - 请考虑使用协议来描述这些类型。通过协议,虽然您从类型检查中获得了改进的安全性,但您不会损失鸭印的精彩甜味和易于测试性,即鸭印始终给您孵育。

并且早期希望使用这些类型提示使您的代码与MyPyc一起快速地制作,虽然它仍然有点过于有限,但记录得太厉害地概括为广泛......↩

我说了帖子的标题,在帖子中! 我喜欢它的时候。 ↩ 我有另一个帖子,即将使用zope.interface与mypy,它结合了摘要的协议和避免了传统的继承,以防止类似的签名所谓的类似签名,而是否则。 ↩ Mypy本身的官方文档甚至标题为“协议和结构化”。 ↩