Python教程-什么是Python中的鸭子类型?

在本教程中,我们将学习鸭子类型。这是Python中一个流行的术语,来源于说法,"如果它走起来像鸭子,游泳像鸭子,看起来像鸭子,那么它可能应该是一只鸭子。"
上面的说法给了我们一个识别鸭子的思路。在这里,我们不需要拥有鸭子的基因序列。我们通过它的行为和外部表现来得出结论。
我们将讨论Python编程中鸭子类型的确切含义。
Python遵循EAFP(Easier to Ask Forgiveness than Permission,宁愿请求宽恕,而不是事先获得许可)哲学,而不是LBLY(Look Before You Leap,先看后跳)哲学。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类,该类具有execute()方法。在Desktop类中,我们在code()中将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_testing函数来反映Duck类的实例。Sparrow类也是如此,它实现了swim()函数。但是在Crocodile类的情况下,它未通过鸭子测试评估,因为它没有实现swim()函数。
鸭子类型如何支持EAFP
鸭子类型是EAFP最合适的风格,因为我们不需要关注对象的"类型"。我们只需要关注它的行为和能力。让我们看看以下陈述。
当我们看到许多if-else块时,这是一种LBYL编程风格。
但是,当我们看到许多try-except块时,这很可能是一位EAFP编程者。