了解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 2 ,b 不是一个字符串。因此,如果我们声明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'
在上面的三个类中,duck 和goose 可以游泳和飞行。然而,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() 方法来创建一个自定义类的迭代器。
要计算的平方数在2 和6 之间。我们使用一个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中动态类型的一个完美例子。它将相关的功能优先于特定的数据类型。
因此,你可以使用从这篇文章中获得的知识来制作其他高质量的应用程序。