Python中的鸭子类型是什么?

2025年3月17日 | 阅读 3 分钟

在本教程中,我们将学习鸭子类型。它是Python中一个流行的术语,源自这样的说法:“如果它像鸭子一样走路,像鸭子一样游泳,像鸭子一样看起来,那么它可能应该是一只鸭子。

上述陈述给了我们一个识别鸭子的方法。这里我们不需要知道鸭子的基因序列。我们通过它的行为和外表来得出结论。

我们将讨论Python编程中鸭子类型的确切含义。

Python遵循EAFP(更容易请求原谅而不是请求许可)原则,而不是LBLY(三思而后行)原则。EAFP在某种程度上与“鸭子类型”风格相关。

动态类型 vs. 静态类型

使用鸭子类型的主要原因是支持Python编程中的动态类型。在Python中,我们不需要指定变量的数据类型,并且可以在后续代码中为同一个变量重新赋值不同的数据类型。让我们看下面的例子。

示例 -

输出

<class 'int'>
<class 'str'>
<class 'list'>

正如我们在上面的代码中看到的,我们将一个整数赋给了变量x,使其成为int类型。然后,我们将一个字符串和一个列表赋给了同一个变量。Python解释器接受了同一个变量的数据类型更改。这是动态类型行为。

许多其他编程语言,如Java、Swift是静态类型的。我们需要声明带有数据类型的变量。在下面的示例中,我们尝试使用Swift而不是Python来执行相同的操作。

示例 -

上面的代码无法编译,因为我们无法在Swift语言中赋值一个字符串。因为变量a被声明为整数。

鸭子类型概念

前面我们已经讨论过Python是一种动态类型的语言。但是,我们可以对自定义数据类型使用动态方法。让我们来理解下面的例子。

示例 -

输出

Compiling
Running
Spell Check
Convention Check

在上面的代码中,我们创建了一个具有execute()方法的VisualStudio类。在desktop-class中,我们在code()中将ide作为参数传递。ide是VisualStudio类的对象。借助ide,我们调用了VisualStudio类的execute()方法。

让我们看另一个例子。

示例 - 2

输出

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_testing函数来反映Duck类的实例。当使用实现swim()函数的Sparrow类时,也会发生这种情况。但在Crocodile类的情况下,它未能通过鸭子测试评估,因为它没有实现swim()函数。

鸭子类型如何支持EAFP

鸭子类型是EAFP最合适的方式,因为我们不需要关注对象的“类型”。我们只需要关心它的行为能力。让我们看下面的陈述。

当我们看到很多if-else块时,那就是LBYL编码风格。

但是如果我们看到很多try-except块,那么很可能这是一个EAFP编码者。


下一主题Python中的PEP 8