跳转至

鸭子类型兼容性

在 Python 中,某些类型是兼容的,即使它们不是彼此的子类。 例如,每当需要 float 对象时,int对象都是有效的。 Mypy 通过 duck 类型兼容性 支持这种习惯用法。 一小组内置类型支持这一点:

  • int 是与 floatcomplex 兼容的鸭子类型。
  • float 是与 complex 兼容的鸭子类型。
  • bytearraymemoryview 是与 bytes 兼容的鸭子类型。

例如,只要需要 float 对象,mypy 就会认为 int 对象有效。 因此,这样的代码干净整洁,并且行为也符合预期:

import math

def degrees_to_radians(degrees: float) -> float:
    return math.pi * degrees / 180

n = 90  # 推断类型“int”
print(degrees_to_radians(n))  # Okay!

您还可以经常使用协议和结构子类型以更有原则和可扩展的方式实现类似的效果。 协议不适用于像intfloat兼容的情况,因为float不是一个协议类,而是一个常规的具体类,并且许多标准库函数期望float(或int)的具体实例 `)。

Duck type compatibility

In Python, certain types are compatible even though they aren't subclasses of each other. For example, int objects are valid whenever float objects are expected. Mypy supports this idiom via duck type compatibility. This is supported for a small set of built-in types:

  • int is duck type compatible with float and complex.
  • float is duck type compatible with complex.
  • bytearray and memoryview are duck type compatible with bytes.

For example, mypy considers an int object to be valid whenever a float object is expected. Thus code like this is nice and clean and also behaves as expected:

import math

def degrees_to_radians(degrees: float) -> float:
    return math.pi * degrees / 180

n = 90  # Inferred type 'int'
print(degrees_to_radians(n))  # Okay!

You can also often use protocol-types to achieve a similar effect in a more principled and extensible fashion. Protocols don't apply to cases like int being compatible with float, since float is not a protocol class but a regular, concrete class, and many standard library functions expect concrete instances of float (or int).


最后更新: 2023年7月6日
创建日期: 2023年7月6日