在本教程中,我们将学习鸭子类型。这是 Python 中的一个流行术语,来源于这样一句话:“如果它走路像鸭子,游泳像鸭子,看起来像鸭子,那么它很可能应该是一只鸭子。”
上面的陈述给出了一个识别鸭子的想法。这里我们不需要有鸭子的基因组序列。我们通过它的行为和外观得出结论。
我们将讨论 Python 编程中鸭子类型的确切含义。
Python 遵循的是 EAFP (请求原谅比请求允许更容易)而不是 LBLY (三思而后行)的哲学。EAFP 与“鸭子类型”风格有些联系。
动态与静态类型
使用鸭式打字的主要原因是为了在 Python 编程中提供动态打字的支持。在 Python 中,我们不需要指定变量的数据类型,我们可以在进一步的代码中将不同的数据类型值重新分配给同一个变量。让我们看看下面的例子。
示例-
x = 12000
print(type(x))
x = 'Dynamic Typing'
print(type(x))
x = [1, 2, 3, 4]
print(type(x))
输出:
<class 'int'>
<class 'str'>
<class 'list'>
正如我们在上面的代码中看到的,我们给变量 x 分配了一个整数,使其成为 int 类型。然后,我们给同一个变量分配了一个字符串和一个列表。Python 解释器接受同一变量数据类型的变化。这是一种动态打字行为。
许多其他编程语言,如 Java、swift 都是静态类型。我们需要用数据类型声明变量。在下面的例子中,我们试图用 Swift 代替 Python 做同样的事情。
示例-
# integer value assigning in JavaScript
var a = 10
# Assinging string in swift
a = 'Swift language'
上面的代码无法编译,因为我们无法用 Swift 语言分配字符串。因为变量 a 被声明为整数。
鸭分型的概念
前面我们已经讨论过 Python 是一种动态类型语言。但是,我们可以将动态方法用于自定义数据类型。让我们理解下面的例子。
示例-
class VisualStudio:
def execute(self):
print('Compiling')
print('Running')
print('Spell Check')
print('Convention Check')
class Desktop:
def code(self, ide):
ide.execute()
ide = VisualStudio()
desk = Desktop()
desk.code(ide)
输出:
Compiling
Running
Spell Check
Convention Check
在上面的代码中,我们已经创建了一个 VisualStudio 类,该类必须执行()方法。在桌面类中,我们在代码()中将 ide 作为参数传递。一个 ide 是 VisualStudio 类的一个对象。在 ide 的帮助下,我们调用了 VisualStudio 类的 execute() 方法。
让我们看另一个例子。
示例- 2
class Duck:
def swim(self):
print("I'm a duck, and I can swim.")
class Sparrow:
def swim(self):
print("I'm a sparrow, and I can swim.")
class Crocodile:
def swim_walk(self):
print("I'm a Crocodile, and I can swim, but not quack.")
def duck_testing(animal):
animal.swim()
duck_testing(Duck())
duck_testing(Sparrow())
duck_testing(Crocodile())
输出:
I'm a duck, and I can swim.
I'm a sparrow, and I can swim.
Traceback (most recent call last):
File "<string>", line 24, in <module>
File "<string>", line 19, in duck_testing
AttributeError: 'Crocodile' object has no attribute 'swim'
在上面的代码中,Duck 类的实例通过调用 duck_testing 函数来反映。麻雀类也是如此,它实现了游()功能。但是在鳄鱼类的例子中,它没有通过鸭子测试评估,因为它没有实现游泳()功能。
鸭子类型如何支持 EAFP
鸭子类型是最适合 EAFP 的风格,因为我们不需要关注对象的“打字”。我们只需要照顾它的行为和功力。让我们看看下面的陈述。
当我们看到很多 if-else 块时,这就是 LBYL 编码风格。
但是如果我们看到大量的尝试——除了块,那么它很可能是一个 EAFP 编码器。