详解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中的元组与逻辑运算符
Oct 13 Python
Python之re操作方法(详解)
Jun 14 Python
Python实现字符串逆序输出功能示例
Jun 24 Python
Python使用Tkinter实现机器人走迷宫
Jan 22 Python
python基于物品协同过滤算法实现代码
May 31 Python
Python将多个list合并为1个list的方法
Jun 27 Python
Python爬取数据保存为Json格式的代码示例
Apr 09 Python
使用Python的Turtle库绘制森林的实例
Dec 18 Python
python操作cfg配置文件方式
Dec 22 Python
Python实现名片管理系统
Feb 14 Python
Python数据可视化图实现过程详解
Jun 12 Python
对象析构函数__del__在Python中何时使用
Mar 22 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
《星际争霸》各版本雷兽特点图文解析 雷兽不同形态一览
2020/03/02 星际争霸
PHP学习之PHP变量
2006/10/09 PHP
php中用文本文件做数据库的实现方法
2008/03/27 PHP
pdo中使用参数化查询sql
2011/08/11 PHP
两千行代码的PHP学习笔记汇总
2014/10/05 PHP
js 获取Listbox选择的值的代码
2010/04/15 Javascript
使用jQuery+HttpHandler+xml模拟一个三级联动的例子
2011/08/09 Javascript
location.href用法总结(最主要的)
2013/12/27 Javascript
javascript笛卡尔积算法实现方法
2015/04/08 Javascript
javascript模拟php函数in_array
2015/04/27 Javascript
JS模拟键盘打字效果的方法
2015/08/05 Javascript
javascript设置页面背景色及背景图片的方法
2015/12/29 Javascript
理解javascript中的MVC模式
2016/01/28 Javascript
JQuery的Pager分页器实现代码
2016/05/03 Javascript
D3.js实现饼状图的方法详解
2016/09/21 Javascript
浅谈微信小程序之官方UI框架we-ui使用教程
2018/08/20 Javascript
详解angularjs跨页面传参遇到的一些问题
2018/11/01 Javascript
详解写好JS条件语句的5条守则
2019/02/28 Javascript
javascript数组去重方法总结(推荐)
2019/03/20 Javascript
微信小程序如何连接Java后台
2019/08/08 Javascript
python爬虫入门教程--HTML文本的解析库BeautifulSoup(四)
2017/05/25 Python
Python实现线程状态监测简单示例
2018/03/28 Python
python 3调用百度OCR API实现剪贴板文字识别
2018/09/04 Python
使用Py2Exe for Python3创建自己的exe程序示例
2018/10/31 Python
使用50行Python代码从零开始实现一个AI平衡小游戏
2018/11/21 Python
利用Tensorboard绘制网络识别准确率和loss曲线实例
2020/02/15 Python
基于Python中random.sample()的替代方案
2020/05/23 Python
python3中确保枚举值代码分析
2020/12/02 Python
Abe’s of Maine:自1979以来销售相机和电子产品
2016/11/21 全球购物
中国网上药店领导者:1药网
2017/02/16 全球购物
android面试问题与答案
2016/12/27 面试题
Linux上比较文件的命令都有哪些
2013/09/28 面试题
领导党性分析材料
2014/02/15 职场文书
2015年社区计生工作总结
2015/04/21 职场文书
Python中递归以及递归遍历目录详解
2021/10/24 Python
JavaScript中isPrototypeOf函数
2021/11/07 Javascript