详解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使用百度API上传文件到百度网盘代码分享
Nov 08 Python
Python中利用sqrt()方法进行平方根计算的教程
May 15 Python
Python的Django框架中模板碎片缓存简介
Jul 24 Python
python去除文件中空格、Tab及回车的方法
Apr 12 Python
Python使用poplib模块和smtplib模块收发电子邮件的教程
Jul 02 Python
对python3标准库httpclient的使用详解
Dec 18 Python
对python调用RPC接口的实例详解
Jan 03 Python
深入了解和应用Python 装饰器 @decorator
Apr 02 Python
基于Django框架的权限组件rbac实例讲解
Aug 31 Python
Python any()函数的使用方法
Oct 28 Python
python打印文件的前几行或最后几行教程
Feb 13 Python
Python自动操作神器PyAutoGUI的使用教程
Jun 16 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 csv操作类代码
2009/12/14 PHP
php入门学习知识点四 PHP正则表达式基本应用
2011/07/14 PHP
PHP中将网页导出为Word文档的代码
2012/05/25 PHP
PHP以mysqli方式连接类完整代码实例
2014/07/15 PHP
PHP设置images目录不充许http访问的方法
2016/11/01 PHP
thinkPHP中钩子的使用方法实例分析
2017/11/16 PHP
在多个页面使用同一个HTML片段《续》
2011/03/04 Javascript
仿中关村在线首页弹出式广告插件(jQuery版)
2012/05/03 Javascript
首页图片漂浮效果示例代码
2014/06/05 Javascript
javascript里使用php代码实例
2014/12/13 Javascript
基于jquery animate操作css样式属性小结
2015/11/27 Javascript
微信小程序-拍照或选择图片并上传文件
2017/01/06 Javascript
Angular4 中常用的指令入门总结
2017/06/12 Javascript
React应用中使用Bootstrap的方法
2017/08/15 Javascript
微信小程序实战篇之购物车的实现代码示例
2017/11/30 Javascript
JS实现简单的浮动碰撞效果示例
2017/12/28 Javascript
详解nodejs通过响应回写的方式渲染页面资源
2018/04/07 NodeJs
angularJs中orderBy筛选以及filter过滤数据的方法
2018/09/30 Javascript
layui 弹出层值回传解决方式
2019/11/14 Javascript
js轮播图之旋转木马效果
2020/10/13 Javascript
关于IDEA中的.VUE文件报错 Export declarations are not supported by current JavaScript version
2020/10/17 Javascript
在Django框架中编写Context处理器的方法
2015/07/20 Python
Python3.6简单操作Mysql数据库
2017/09/12 Python
python实现最长公共子序列
2018/05/22 Python
python flask 如何修改默认端口号的方法步骤
2019/07/12 Python
Bootstrap 学习分享
2012/11/12 HTML / CSS
Dr. Martens马汀博士官网:马丁靴始祖品牌
2016/10/15 全球购物
加拿大当代时尚服饰、配饰和鞋类专业零售商和制造商:LE CHÂTEAU
2017/10/06 全球购物
固特异美国在线轮胎店:Goodyear Tire
2019/02/23 全球购物
如何在发生故障的节点上重新安装 SQL Server
2013/03/14 面试题
外语专业毕业生自我评价分享
2013/10/05 职场文书
关于清明节的演讲稿
2014/09/13 职场文书
反四风对照检查材料思想汇报
2014/09/16 职场文书
2014年第四季度入党积极分子思想汇报(十八届四中全会)
2014/11/03 职场文书
幼儿园托班教育随笔
2015/08/14 职场文书
Android使用EventBus发送消息,Fragment中接收消息的方法会执行多次
2022/04/24 Java/Android