Python语言的鸭子类型
小标 2018-11-14 来源 : 阅读 1143 评论 0

摘要:本文主要向大家介绍了Python语言的鸭子类型,通过具体的内容向大家展示,希望对大家学习Python语言有所帮助。

本文主要向大家介绍了Python语言的鸭子类型,通过具体的内容向大家展示,希望对大家学习Python语言有所帮助。

‘那只东西呱呱的叫,有扁扁的嘴巴,走起路来还外八,对!它就是只鸭子’基本定义对于熟悉python的开发者来说,相信对于python的鸭子类型比较熟悉,所谓鸭子类型,在维基百科中的准确定义是‘是动态类型的一种风格。在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由"当前方法和属性的集合"决定’。python中的具体实现下面的代码就是一个简单的鸭子类型class duck():
    def walk(self):
        print('I walk like a duck')    def swim(self):
        print('i swim like a duck')class person():
    def walk(self):
        print('this one walk like a duck') 
    def swim(self):
        print('this man swim like a duck')对于一个鸭子类型来说,我们并不关心这个对象的类型本身或是这个类继承,而是这个类是如何被使用的。我们可以通过下面的代码来调用这些类的方法。def watch_duck(animal):
    animal.walk()
    animal.swim()

small_duck = duck()
watch_duck(small_duck)

output >> 
I walk like a duck
i swim like a duck


duck_like_man = person()
watch_duck(duck_like_man)

output >> 
this one walk like a duck
this man swim like a duckclass Lame_Foot_Duck():
    def swim(self):
        print('i am lame but i can swim')

lame_duck = Lame_Foot_Duck()
watch_duck(lame_duck)

output >>AttributeError: Lame_Foot_Duck instance has no attribute 'walk'watch_duck函数接收这个类的对象,然后并没有检查对象的类型,而是直接调用这个对象的走和游的方法,如果所需要的方法不存在就报错。具体在python中鸭子类型的体现如下面的代码所示class CollectionClass():
    lists = [1,2,3,4]    def __getitem__(self, index):        return self.lists[index]

iter_able_object = CollectionClass()class Another_iterAbleClass():
    lists=[1,2,3,4]
    list_position = -1

    def __iter__(self):        return self

    def next(self): #还有更简单的实现,使用生成器或迭代器什么的:)
        self.list_position += 1
        if self.list_position >3:
            raise StopIteration        return self.lists[self.list_position]

another_iterable_object=Another_iterAbleClass()

print(iter_able_object[1])
print(iter_able_object[1:3])
output>>2[2, 3]

another_iterable_object[2]
output>>Traceback (most recent call last):
  File "/Users/steinliber/a.py", line 32, in 
    another_iterable_object[2]TypeError: 'Another_iterAbleClass' object does not support indexing

print(next(another_iterable_object))
output>>1print(next(another_iterable_object))
output>>2print(next(iter_able_object))
output>>Traceback (most recent call last):
  File "/Users/steinliber/a.py", line 29, in 
    print(next(iter_able_object))TypeError: IterAbleClass object is not an iterator在python把上述代码的实现方法叫做protocol(协议),这些protocol可以看作是通知型的接口,它规定了调用方使用该功能要调用对象的哪些方法,被调用方要实现哪些方法才能完成这个功能。它和java中的接口区别在于java中的接口功能实现需要通过继承,继承的类必须实现接口中的所有的抽象方法,所以在Java中强调的是类型的概念,而python中的protocol更多的是通知性的,一个函数规定要实现某个功能需要调用传入对象的哪些方法,所有实现这些方法的类就可以实现这个功能。具体从上面两个类来说,第一个类实现了__getitem__方法,那python的解释器就会把它当做一个collection,就可以在这个类的对象上使用切片,获取子项等方法,第二个类实现了__iter__和next方法,python就会认为它是一个iterator,就可以在这个类的对象上通过循环来获取各个子项。一个类可以实现它有能力实现的方法,并只能被用于在它有意义的情况下。这两个类和上面的鸭子类相比较,其实用于切边的[](它其实调用的是python的slice函数)和用于循环的iter()就相当于watch_duck函数,这些函数都接收任意类的对象,并调用实现功能所需要的对象中的方法来实现功能,若该函数中调用的方法对象里面不存在,就报错。从上面可以看出,python鸭子类型的灵活性在于它关注的是这个所调用的对象是如何被使用的,而没有关注对象类型的本身是什么。所以在python中使用isinstance来判断传入参数的类型是不提倡的,更pythonic的方法是直接使用传入的参数,通过try,except来处理传入参数不符合要求的情况。我们应该通过传入对象的能力而不是传入对象的类型来使用该对象。

本文由职坐标整理并发布,希望对同学们学习Python有所帮助,更多内容请关注职坐标编程语言Python频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 1 不喜欢 | 0
看完这篇文章有何感觉?已经有1人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程