欢迎访问Python每天3分钟系列。每天花3分钟时间,学习或温习一个Python知识点。今天是第034篇:

Duck Typing 鸭子类型
Python界有这么一句话:
“只要你走路像鸭子,叫起来像鸭子,我就把你当成鸭子。
这就是传说中的鸭子类型,用来形容Python对待类型的一种态度。它有别于Java等强类型语言。
Java对待类型的态度是:
“你必须是真正的鸭子(或者继承自鸭子),否则就算你走路像鸭子,叫起来像鸭子也不行。
来,上代码!
这是鸭子类,它有两个关键方法:鸭子叫,鸭子步。
class Duck:
def duck_walk(self):
print('走?步')
def duck_sound(self):
print('嘎嘎嘎')
这是全聚德,一个对鸭子来说很可怕的地方,它有一个静态方法cook
用来招待送来的鸭子:
# 全聚德
class QuanJude:
@staticmethod
def cook(duck):
print("-- 鸭子来了,先检查一下 ---")
# 走走看
duck.duck_walk()
# 叫两声听听
duck.duck_sound()
print("验证完毕,可以下锅了")
这一直运行良好:
# 搞两只鸭子
d1 = Duck()
d2 = Duck()
# 送到全聚德
QuanJude.cook(d1)
QuanJude.cook(d1)
运行结果:
-- 鸭子来了,先检查一下 ---
走?步
嘎嘎嘎
验证完毕,可以下锅了
-- 鸭子来了,先检查一下 ---
走?步
嘎嘎嘎
验证完毕,可以下锅了
可是有一种鸡,从小就在鸭子群里长大,它们学习能力很强,也学会了鸭子步和鸭子叫:
class Chicken:
def __init__(self):
print('我其实是一个小鸡,谁说小鸡不会鸭子叫呢!')
def duck_walk(self):
print('走?步')
def duck_sound(self):
print('嘎嘎嘎')
有一天,它们也被送到了全聚德。你看多学点东西总是好的,可以去高级餐厅。
# 抓了两只鸡
c1 = Chicken()
c2 = Chicken()
# 送到全聚德
QuanJude.cook(c1)
QuanJude.cook(c1)
运行结果:
我其实是一个小鸡,谁说小鸡不会鸭子叫呢!
我其实是一个小鸡,谁说小鸡不会鸭子叫呢!
-- 鸭子来了,先检查一下 ---
走?步
嘎嘎嘎
验证完毕,可以下锅了
-- 鸭子来了,先检查一下 ---
走?步
嘎嘎嘎
验证完毕,可以下锅了
这说明cook方法根本不在意你是鸭子还是鸡,或者别的。只要你有那两个方法,就把你当成鸭子煮了! 简单粗暴!
这也没什么大不了。烤鸭烤出来一直鸡也还凑合吧。直到有一天…
有些很顽皮的小朋友,他们也学会了鸭子叫,也会走鸭子步:
class NaughtyBoy:
def __init__(self):
print('我是顽皮的小朋友,嘻嘻嘻')
def duck_walk(self):
print('走?步')
def duck_sound(self):
print('嘎嘎嘎')
有一天他不小心,溜溜达达,走到了全聚德的后厨门口。好奇心来了,他们决定进去看看….
总结一下:
-
Python不在意类型,只要对象具有相应的方法就可以。这就是所谓的鸭子类型! 只要你走路像鸭子,叫起来像鸭子,我就把你当成鸭子。 -
鸭子类型的好处是方便,你只要给类加上相应的方法就能用,不一定要继承特定的父类。 -
鸭子类型的坏处就是不安全。上面发生的事情,在Java中是绝对不会发生的,因为Java在编译时会首先检查类型是不是Duck。
自我感觉今天的3分钟还比较有意思。麦友小伙伴们,如果你也这么认为,考虑转发一下?谢谢!
声明:本网站资源来源于网络收集,如有侵权,请联系站长进行删除处理。 分享目的仅供大家学习和交流,请不要用于商业用途,否则后果自负。本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解。本站资源售价只是赞助,收取费用仅维持本站的日常运营所需。反馈邮箱:1159995880@qq.com
评论(0)