了解Python中的Duck类型

155 阅读5分钟

了解Python中的Duck 类型

Duck 类型是一种动态的语言系统类型。一个对象所指定的方法比其类型更重要。因此,我们不使用Duck typing。

本文通过研究几种编程语言的类型和Duck类型,来比较静态与动态类型。

前提条件

要理解这篇文章,你需要具备。

  • 对Python编程有一定的了解
  • 安装了一个Python编译器。

理解静态和动态类型化

类型检查是在实时的基础上使用动态类型来进行的。例如,Python是动态类型化的。

这意味着一个变量的类型可能随时间变化。同样地,Perl、Ruby、PHP和JavaScript也是动态类型的。

让我们来看看一个变量在Python中如何改变类型。

b ="hurry"
print(type(b))
b = 4
print(type(b))
<class 'str'>
<class 'int'> 

上面的代码将变量b 赋值为字符串hurry 和一个整数值4 。这可以确保 Python 正确推断出变量的类型。

静态类型法在编译过程中检查类型。一些语言如C、C++和Java指定了变量的类型,而其他语言如Scala和Haskell可以进行类型推断。静态类型化避免了变量的重复输入。

下面是一个静态类型语言的基本例子。

String b;
b = "Programming is the best choice";

上面的代码输出了以下错误信息。

File "main.py", line 8
    String b;
           ^
SyntaxError: invalid syntax

第一行将b 声明为一个string 。在line 2b 不是一个字符串。因此,如果我们声明b = 4 ,它将警告类型不兼容。

Python中的静态和动态类型化

一个计算机程序的对象和元素被存储在内存中,并且有变量名。当一个特定类的对象被创建时,它将被分配内存并通过其变量名来调用。

你可以把这个内存空间看作是一个盒子或容器。这意味着我们有两个组成部分;一个物品和它的包装。

一个盒子必须是为了容纳它所包含的东西而建造的(例如,一个为保存笔而制造的盒子不会是携带纺织品的最佳选择)。一个物品和盒子必须是相同的。

这被称为静态类型,因为对象和变量名(盒子)都必须具有相同的类型

这就解释了为什么在Java/C++这样的静态类型语言中,你必须声明一个变量的类型。即使这个变量是空的,你也可以把它指定为一个盒子。Python 不支持这种功能。

Python 是一种动态类型的语言。变量的名字更像是商店的价格标签,而不是一个盒子。所以标签是空白的。如果你问它的类型,它可能会选择被标记的对象。

一个服装标签可以在另一件衣服上重复使用。因此,Python不明确地对变量进行类型化。

Duck类型化的概念

我们构造三个类:Duck、鹅和河马。它们都会游泳。Duck和鹅会飞,但河马会走。

接下来,我们定义swim_fly() 函数,它接受一个动物并输出其特征。

由于变量类型的问题,一个缺少swim_fly() 函数的生物将无法通过鸭子的测试。

让我们看一下Duck类型的例子。

class Duck:  
   def swim_fly(self):  
         print("I am a duck, and I can swim and fly.")  
   
class Goose:  
     def swim_fly(self):  
         print("I am a Goose, and I can swim and fly.")  
   
class Hippo:  
     def walk(self):  
         print("I am a Hippo, and I can swim but can't fly.")  
   
for obj in Duck(), Goose(), Hippo():
    obj.swim_fly()
I am a duck, and I can swim and fly.
I am a Goose, and I can swim and fly.
Traceback (most recent call last):
  File "main.py", line 21, in <module>
    obj.swim_fly()
AttributeError: 'Hippo' object has no attribute 'swim_fly'

在上面的三个类中,duckgoose 可以游泳和飞行。然而,hippo 类缺乏游泳飞行方法。因此,它的实例没有通过测试。

这给了我们一个鸭子类型的基本记号。自定义类型更多的是关于实现功能而不是数据类型。尽管鹅并不是一只真正的鸭子,但swim_fly 函数将它变成了一只鸭子。

实际例子

现在让我们考虑一些我们可以在我们的项目中应用的Duck类型的用法。

如何在Duck类型中应用迭代

迭代允许我们在 Python 中修改列表。for 循环是一种建立迭代的系统方法。

由于Duck typing的存在,这些对象的处理方式是相同的,无论其应用如何。迭代需要iter() 和next() 方法。

在Python中,我们可以利用iter()和next()等方法设计我们的迭代器,用于输出平方数。

class Number_squared:
  def __init__(identity, l=0, x=-1):
    identity.x = x
    identity.y = l
  def __iter__(identity):
    return identity
  def __next__(identity):
    if identity.y < identity.x:
      s = identity.y ** 2
      identity.y += 1
      return s
    else:
      raise StopIteration    
for k in Number_squared(2, 6):
  print(k)
4
9
16
25

在上面的代码中,我们利用iter()next() 方法来创建一个自定义类的迭代器。

要计算的平方数在26 之间。我们使用一个for 循环来浏览这些数字。

自定义len()函数的实现

自定义len() 方法使用sort() 方法对一个列表进行排序。例如,考虑按照名字的长度对一个列表进行排序。下面是鸭子打字的工作原理。

def length(iterator):
   count = 0
   for item in iterator:
    
      count += 1
   return count
if __name__ == "__main__":
   iterator = input("Enter a string:- ")
   print(f"Length of {iterator} is {length(iterator)}")

上面的代码提示用户输入一个字符串。然后它计算字符串的长度并返回结果。

def length(iterator) 是用来声明检索迭代器长度的函数,并使用 ,将 设置为零。count =0 count

for 循环增加count ,每次计数后加一,并将值返回给函数。

iterator = input("Enter a string:- ") 提示用户输入一个字符串,并使用 ,返回该字符串的长度。print(f"Length of {iterator} is {length(iterator)}")

结论

Duck类型是Python中动态类型的一个完美例子。它将相关的功能优先于特定的数据类型。

因此,你可以使用从这篇文章中获得的知识来制作其他高质量的应用程序。