如何使用结构子类型
Python 3.8引入了一个新的特性:协议。协议是抽象基类(ABC)的一种替代方案,可以基于可用的属性和函数来检查两个类是否兼容。在本文中,我们将详细介绍这个特性,并展示如何使用实际示例来使用协议。
Python中的类型
让我们先讨论Python的类型。它是一种动态类型语言,意味着类型是在运行时推断的,以下代码可以正常运行:
def add(x, y): return x + yprint(add(2, 3))print(add("str1", "str2"))
第一次调用返回整数相加的结果5,第二次调用返回字符串连接的结果“str1str2”。这与C++等静态类型语言不同,静态类型语言需要提供类型声明:
int add(int x, int y) { return x + y;}std::string add(std::string x, std::string y) { return x + y;}int main(){ std::cout<<add(2, 3); std::cout << add("str1", "str2"); return 0;}
静态类型提供了在编译时捕获错误的优势,而在动态类型语言中,我们只能在运行时遇到这些错误。另一方面,动态类型可以实现更快的原型设计和实验,这也是Python变得如此流行的原因之一。
动态类型也被称为鸭子类型,基于一句话:“如果它走起来像鸭子,叫起来像鸭子,那么它一定是鸭子”。因此,如果对象具有相同的属性/函数,它们应该被类似地对待,例如可以传递给需要其他类型的函数。
然而,特别是在较大的、更专业的软件产品中,这种不可靠性带来的负面影响多于正面影响,因此趋势是向静态类型检查发展,例如通过使用mypy提供类型提示。
子类型
一个有趣的问题,如上所示,例如在关于鸭子类型的简短段落中,是子类型。如果我们有一个带有签名foo(x: X)
的函数,除了X
之外,mypy允许哪些其他类被传递给该函数?(请注意,我们现在只有…)