详解duck typing鸭子类型程序设计与Python的实现示例


Posted in Python onJune 03, 2016

在程序设计中,鸭子类型(英语:duck typing)是动态类型的一种风格。在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由当前方法和属性的集合决定。
这个概念的名字来源于由James Whitcomb Riley提出的鸭子测试,“鸭子测试”可以这样表述:
“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”
在鸭子类型中,关注的不是对象的类型本身,而是它是如何使用的。例如,在不使用鸭子类型的语言中,我们可以编写一个函数,它接受一个类型为鸭的对象,并调用它的走和叫方法。在使用鸭子类型的语言中,这样的一个函数可以接受一个任意类型的对象,并调用它的走和叫方法。如果这些需要被调用的方法不存在,那么将引发一个运行时错误。任何拥有这样的正确的走和叫方法的对象都可被函数接受的这种行为引出了以上表述,这种决定类型的方式因此得名。
鸭子类型通常得益于不测试方法和函数中参数的类型,而是依赖文档、清晰的代码和测试来确保正确使用。从静态类型语言转向动态类型语言的用户通常试图添加一些静态的(在运行之前的)类型检查,从而影响了鸭子类型的益处和可伸缩性,并约束了语言的动态特性。

Python代码示例
上面这样说可能太空洞了。比如在Python中,有很多file-like的东西,比如StringIO,GzipFile,socket。它们有很多相同的方法,我们把它们当作文件使用。
又比如list.extend()方法中,我们并不关心它的参数是不是list,只要它是可迭代的,所以它的参数可以是list/tuple/dict/字符串/生成器等.
鸭子类型在动态语言中经常使用,非常灵活,使得python不想java那样专门去弄一大堆的设计模式。

下面例子用duck typing来实现多态。

#coding=utf-8 
class Duck: 
  def quack(self): 
    print "Quaaaaaack!" 
 
class Bird: 
  def quack(self): 
    print "bird imitate duck." 
 
class Doge: 
  def quack(self): 
    print "doge imitate duck." 
 
def in_the_forest(duck): 
  duck.quack() 
 
duck = Duck() 
bird = Bird() 
doge = Doge() 
for x in [duck, bird, doge]: 
  in_the_forest(x)

再举个栗子,
我们来hack输出流。

import sys 
 
sys.stdout = open('stdout.log', 'a') #只要是file-like,不管是什么类型 
print 'foo' 
 
sys.stdout = sys.__stdout__ #恢复 
print 'bar'

这样就把输出流给写入到文件中去了。

Python 相关文章推荐
python生成随机密码或随机字符串的方法
Jul 03 Python
使用FastCGI部署Python的Django应用的教程
Jul 22 Python
Python简单定义与使用二叉树示例
May 11 Python
python opencv实现图片旋转矩形分割
Jul 26 Python
Flask框架钩子函数功能与用法分析
Aug 02 Python
python opencv实现证件照换底功能
Aug 19 Python
详解Python3中的 input() 函数
Mar 18 Python
Django在Model保存前记录日志实例
May 14 Python
tensorflow dataset.shuffle、dataset.batch、dataset.repeat顺序区别详解
Jun 03 Python
python使用隐式循环快速求和的实现示例
Sep 11 Python
手把手教你从PyCharm安装到激活(最新激活码),亲测有效可激活至2089年
Nov 25 Python
python tkinter实现下载进度条及抖音视频去水印原理
Feb 07 Python
详解字典树Trie结构及其Python代码实现
Jun 03 #Python
Python中利用Scipy包的SIFT方法进行图片识别的实例教程
Jun 03 #Python
Python中的descriptor描述器简明使用指南
Jun 02 #Python
Python黑魔法Descriptor描述符的实例解析
Jun 02 #Python
深入理解Python变量与常量
Jun 02 #Python
Python中的Descriptor描述符学习教程
Jun 02 #Python
从源码解析Python的Flask框架中request对象的用法
Jun 02 #Python
You might like
php PDO中文乱码解决办法
2009/07/20 PHP
PHP之数组学习
2011/05/29 PHP
PDO版本问题 Invalid parameter number: no parameters were bound
2013/01/06 PHP
php去除二维数组的重复项方法
2015/11/03 PHP
Yii框架中jquery表单验证插件用法示例
2016/10/18 PHP
[原创]PHP实现SQL语句格式化功能的方法
2017/07/28 PHP
js控制框架刷新
2008/08/01 Javascript
基于jquery的bankInput银行卡账号格式化
2012/08/22 Javascript
angularJS提交表单(form)
2015/02/09 Javascript
理解JS绑定事件
2016/01/19 Javascript
AngularJS整合Springmvc、Spring、Mybatis搭建开发环境
2016/02/25 Javascript
基于javascript实现图片切换效果
2016/04/17 Javascript
JS中用三种方式实现导航菜单中的二级下拉菜单
2016/10/31 Javascript
jquery实现input框获取焦点的简单实例
2017/01/26 Javascript
基于JavaScript实现淘宝商品广告效果
2017/08/10 Javascript
React-Router如何进行页面权限管理的方法
2017/12/06 Javascript
详解vue页面首次加载缓慢原因及解决方案
2019/11/06 Javascript
python删除文件示例分享
2014/01/28 Python
Python中集合类型(set)学习小结
2015/01/28 Python
python简单获取本机计算机名和IP地址的方法
2015/06/03 Python
使用Python微信库itchat获得好友和群组已撤回的消息
2018/06/24 Python
python实现连续变量最优分箱详解--CART算法
2019/11/22 Python
python opencv 实现对图像边缘扩充
2020/01/19 Python
python使用OpenCV模块实现图像的融合示例代码
2020/04/10 Python
洛杉矶生活休闲而精致的基础品牌:Mika Jaymes
2018/01/07 全球购物
BannerBuzz加拿大:在线定制横幅印刷、广告和标志
2020/03/10 全球购物
如何在Cookie里面保存Unicode和国际化字符
2013/05/25 面试题
Java里面如何把一个Array数组转换成Collection, List
2013/07/26 面试题
2014学雷锋活动总结
2014/03/09 职场文书
电子商务优秀毕业生求职信
2014/07/11 职场文书
捐款活动总结
2014/08/27 职场文书
交通工程专业推荐信
2014/09/06 职场文书
超市收银员岗位职责
2015/04/07 职场文书
聘任合同书
2015/09/21 职场文书
为什么MySQL选择Repeatable Read作为默认隔离级别
2021/07/26 MySQL
JavaScript中的宏任务和微任务详情
2021/11/27 Javascript