等等!python和鸭子是什么关系?

点击上方“Python爬虫与数据挖掘”,进行关注

回复“书籍”即可获赠Python从入门到进阶共10本电子书

穷则变,变则通,通则久。


众所周知,python是一门编程语言,它可以做的东西很多,爬虫、人工智能、自动化测试、数据分析等等。而鸭子是一种动物,它可以做的东西也很多,啤酒鸭、香烤鸭、盐水鸭、土豆焖鸭等等。按理说这两个对应着不同人体器官的东西应该是扯不上关系的。

但是,偏偏就有辣莫一个人,美国诗人詹姆斯·惠特科姆·莱利,在17世纪时写下了一句诗:

「When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck.」

就是这短短的一句诗,让这两者扯上了神奇的关系,关键人们还为这种关系取了个名字 -- 鸭子类型。从此python和鸭子就成就了一段佳话啊呸,那这鸭子类型究竟是怎么回事呢?且往下看~

思考一个场景

加入在你拥有一款内容聚合应用,这款应用每天会从各个门户网站采集一些文章回来,并且分发至应用里面的各个频道。

这个时候我们可以将分发文章这个功能简单的抽象为一个distribute函数,该函数由两个参数构成,待分发文章article,分发频道channel

同时为了保证文章更符合频道的内容范围和调性,在每篇文章分发至频道时,最好都对文章做一些准入校验,于是我们初步封装出以下函数:

def distribute(article, channel):
    # 文章准入判断
    # 政务频道的文章标题不能出现‘震惊’字眼
    if channel.name == 'politics' and article.title.find('震惊') >= 0:
        return False
    # 娱乐频道不允许a,b这两个作者的文章
    elif channel.name == 'entertainment' and article.author in ['a','b']:
        return False
    # some elif here...

    # 将文章与频道的绑定关系写进数据库
    return bind_relation(article, channel)

上面的函数确实能够实现我们想要的功能了,但是存在一个显而易见的问题:如果我们每增加一条准入规则,就需要改动一次distribute函数,这样频繁地对一个函数动刀显然不是一个好的做法。

我们希望这个函数是一个更抽象的公共函数,他不需要被过多的改动,于是我们做一点改进,变成下面的函数:

def distribute(article, channel):
    # 文章准入判断
    can_push = channel.check(article)

    # 将文章与频道的绑定关系写进数据库
    if can_push:
        return bind_relation(article, channel)
    return False

将校验频道准入规则的这个功能用频道类自己实现的check方法封装起来,这样每当有一个新的频道需要创建,或者旧频道需要更改校验规则,则只需要负责维护各自频道类的check方法就好了。

distribute函数作为一个更高层级的存在则不会被影响到。

class Article:
    def __init__(self, title, author):
        self.title = title
        self.author = author

class EntertainmentChannel:
    def __init__(self)
        self.name = 'entertainment'

    def check(article):
        if article.author in ['a','b']:
            return False
        return True

class PoliticsChannel:
    def __init__(self)
        self.name = 'politics'

    def check(article):
        if article.title.find('震惊') >= 0:
            return False
        return True

aritcle_a = Article('震惊!大笑1小时寿命减少60分钟!', 'a')
aritcle_b = Article('战胜恐惧最好的办法?', 'b')

politics_channel = PoliticsChannel()
entertainment_channel = EntertainmentChannel()

distribute(aritcle_a, politics_channel)  # Fasle
distribute(aritcle_b, entertainment_channel)  # Fasle

多态

上面对于distribute函数的改造结果,其实很类似于面向对象三大特征之一 —— 多态 的应用。

简单解释起来,多态就是同一操作(方法)被作用于不同的对象时,可以有不同的解释,产生不同的执行结果。

例如上面的check方法,当它由EntertainmentChannel类实例调用时,检查的是文章标题不能包含“震惊”字眼;由PoliticsChannel类实例调用时,检查的是文章作者不能是’a'和‘b’。

多态在静态语言如 Java 中,通常通过子类继承父类,然后子类重写父类中的某些方法来实现多态。但是在python中,不需要搞子承父业这一套,只需要在不同的类里面实现好名字相同的方法,即可在运行时表现出多态

只不过,这种特征在python中一般不叫多态,而是我们前面提到的——鸭子类型

鸭子类型

鸭子类型的名字来源和具体应用场景前面已经描述过了,而关于鸭子类型的定义,网上出现最多的就是对文章开头那句英文诗句的翻译:

如果一只鸟走起来像鸭子,发出的声音像鸭子,游起来像鸭子,那么它就是一只鸭子

这句话重点在于引导我们只关注事物的行为,而不是关注事物本身和它的表现。再看一个帮助理解的栗子????:

class Duck:
    def sound(self):
        print('quack')

    def walk(self):
        print('da da da')

class Dog:
    def sound(self):
            print('wang')

    def walk(self):
        print('tita tita tita')

def walk_and_sound(animal):
    animal.walk()
    animal.sound()

dog = Dog()
duck = Duck()

walk_and_sound(dog) # tita tita tita wang
walk_and_sound(duck) # da da da quack

就好像一只狗会走,会叫;鸭子也会走,会叫。狗有很多行为都跟鸭子相似,他们做的动作是一样的,只是表现出来不一样。

我们关注的是类有什么方法,能做什么,而不是类是怎么定义的,表现出来是怎么样的。这个正是鸭子类型想表达的思想。

鸭子类型的思想

总结

  • 鸭子类型是python中多态的一种实现方式。

  • 鸭子类型强调关注事物的行为而不是事物本身和事物的表现,如果某些类都实现了同名方法,那这些类就符合鸭子类型

后记&引用

其实我仔细想了想,如果我早出生几个世纪,在詹姆斯·惠特科姆·莱利写出那句诗之前,喊出 「如果一个四肢动物走起来像狗,叫起来像狗,傻起来像狗,那它就是一只狗」~这样一句话。

是不是现在就不叫鸭子类型而改叫狗子类型呢?唉,又错过了名留千史的机会,还是应了一句老话:出名要趁早啊!

------------------- End -------------------

往期精彩文章推荐:

欢迎大家点赞,留言,转发,转载,感谢大家的相伴与支持

想加入Python学习群请在后台回复【入群

万水千山总是情,点个【在看】行不行

/今日留言主题/

随便说一两句吧~~

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、下载 4使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、 4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.m或d论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 、1资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值