详解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中实现对list做减法操作介绍
Jan 09 Python
python中__slots__用法实例
Jun 04 Python
Windows中安装使用Virtualenv来创建独立Python环境
May 31 Python
利用python爬取散文网的文章实例教程
Jun 18 Python
利用python将图片转换成excel文档格式
Dec 30 Python
详解Python使用tensorflow入门指南
Feb 09 Python
Python使用分布式锁的代码演示示例
Jul 30 Python
Python 中 function(#) (X)格式 和 (#)在Python3.*中的注意事项
Nov 30 Python
Python中单线程、多线程和多进程的效率对比实验实例
May 14 Python
python+tkinter实现学生管理系统
Aug 20 Python
Python : turtle色彩控制实例详解
Jan 19 Python
浅谈Python描述数据结构之KMP篇
Sep 06 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
Zend Guard一些常见问题解答
2008/09/11 PHP
PHP缓存机制Output Control详解
2014/07/14 PHP
PHP常见的序列化与反序列化操作实例分析
2019/10/28 PHP
php设计模式之原型模式分析【星际争霸游戏案例】
2020/03/23 PHP
用js实现上传图片前的预览(TX的面试题)
2007/08/14 Javascript
JQuery 选择器 xpath 语法应用
2010/05/13 Javascript
ajax异步刷新实现更新数据库
2012/12/03 Javascript
解析Javascript中中括号“[]”的多义性
2013/12/03 Javascript
Javascript连接多个数组不用concat来解决
2014/03/24 Javascript
jQuery基于ajax实现带动画效果无刷新柱状图投票代码
2015/08/10 Javascript
Bootstrap布局组件应用实例讲解
2016/02/17 Javascript
jquery获取img的src值的简单实例
2016/05/17 Javascript
yii form 表单提交之前JS在提交按钮的验证方法
2017/03/15 Javascript
基于vue2实现左滑删除功能
2017/11/28 Javascript
vue router动态路由下让每个子路由都是独立组件的解决方案
2018/04/24 Javascript
vue 不使用select实现下拉框功能(推荐)
2018/05/17 Javascript
jQuery基于闭包实现的显示与隐藏div功能示例
2018/06/09 jQuery
Vue实现手机号、验证码登录(60s禁用倒计时)
2020/12/19 Vue.js
[56:00]2018DOTA2亚洲邀请赛 4.6 淘汰赛 VP vs TNC 第二场
2018/04/10 DOTA
python自动安装pip
2014/04/24 Python
python中argparse模块用法实例详解
2015/06/03 Python
python解决js文件utf-8编码乱码问题(推荐)
2018/05/02 Python
Python小进度条显示代码
2019/03/05 Python
对python中GUI,Label和Button的实例详解
2019/06/27 Python
在PyCharm的 Terminal(终端)切换Python版本的方法
2019/08/02 Python
Python Subprocess模块原理及实例
2019/08/26 Python
python实现简单遗传算法
2020/09/18 Python
美国中西部家用医疗设备商店:Med Mart(轮椅、踏板车、升降机等)
2019/04/26 全球购物
超级英雄、电影和电视、乐队和音乐T恤:Loud Clothing
2019/09/01 全球购物
长青弘远的面试题
2012/06/09 面试题
教育学习自我评价
2014/02/03 职场文书
2014年新生军训方案
2014/05/01 职场文书
班级课外活动总结
2014/07/09 职场文书
大学教师师德师风演讲稿
2014/08/22 职场文书
小学生感恩父母演讲稿
2014/08/28 职场文书
2016年党员干部廉政承诺书
2016/03/24 职场文书