详解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 21 Python
Python正则表达式知识汇总
Sep 22 Python
Python cookbook(数据结构与算法)从序列中移除重复项且保持元素间顺序不变的方法
Mar 13 Python
python去除文件中重复的行实例
Jun 29 Python
python3中函数参数的四种简单用法
Jul 09 Python
python使用numpy读取、保存txt数据的实例
Oct 14 Python
浅谈Python 多进程默认不能共享全局变量的问题
Jan 11 Python
详解Python安装tesserocr遇到的各种问题及解决办法
Mar 07 Python
Python之Numpy的超实用基础详细教程
Oct 23 Python
浅谈Python中range与Numpy中arange的比较
Mar 11 Python
Python Scrapy图片爬取原理及代码实例
Jun 12 Python
pycharm2021激活码使用教程(永久激活亲测可用)
Mar 30 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中str_replace函数使用小结
2008/10/11 PHP
php+ajax实现无刷新动态加载数据技术
2015/04/28 PHP
Thinkphp3.2简单解决多文件上传只上传一张的问题
2017/09/26 PHP
PHP设计模式(七)组合模式Composite实例详解【结构型】
2020/05/02 PHP
Javascript技术栈中的四种依赖注入小结
2016/02/27 Javascript
jQuery解决$符号命名冲突
2016/06/18 Javascript
AngularJS基础 ng-selected 指令简单示例
2016/08/03 Javascript
Bootstrap实现圆角、圆形头像和响应式图片
2016/12/14 Javascript
JavaScript 字符串数字左补位,右补位,取固定长度,截位扩展函数代码
2017/03/25 Javascript
js CSS3实现卡牌旋转切换效果
2017/07/04 Javascript
基于滚动条位置判断的简单实例
2017/12/14 Javascript
JavaScript常用截取字符串的三种方式用法区别实例解析
2018/05/15 Javascript
vue模块拖拽实现示例代码
2019/03/09 Javascript
vue路由--网站导航功能详解
2019/03/29 Javascript
jquery中为什么能用$操作
2019/06/18 jQuery
JS数组splice操作实例分析
2019/10/12 Javascript
vue路由缓存的几种实现方式小结
2020/02/02 Javascript
在Python的框架中为MySQL实现restful接口的教程
2015/04/08 Python
使用rst2pdf实现将sphinx生成PDF
2016/06/07 Python
使用Django Form解决表单数据无法动态刷新的两种方法
2017/07/14 Python
Python处理CSV与List的转换方法
2018/04/19 Python
python实现从文件中读取数据并绘制成 x y 轴图形的方法
2018/10/14 Python
详解Django-auth-ldap 配置方法
2018/12/10 Python
Python 正则表达式匹配字符串中的http链接方法
2018/12/25 Python
python3.6、opencv安装环境搭建过程(图文教程)
2019/11/05 Python
python 用opencv实现图像修复和图像金字塔
2020/11/27 Python
python爬虫beautifulsoup库使用操作教程全解(python爬虫基础入门)
2021/02/19 Python
携程英文网站:Trip.com
2017/02/07 全球购物
在C++ 程序中调用被C 编译器编译后的函数,为什么要加extern "C"
2014/08/09 面试题
酒店副总经理岗位职责范本
2014/02/04 职场文书
关爱残疾人标语
2014/06/25 职场文书
优秀党员个人总结
2015/02/14 职场文书
python实现腾讯滑块验证码识别
2021/04/27 Python
如何理解Vue简单状态管理之store模式
2021/05/15 Vue.js
在Python中如何使用yield
2021/06/07 Python
 python中的元类metaclass详情
2022/05/30 Python