详解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和str比较
Sep 20 Python
Python pickle模块用法实例
Apr 14 Python
python append、extend与insert的区别
Oct 13 Python
Python 迭代器与生成器实例详解
May 18 Python
对python使用http、https代理的实例讲解
May 07 Python
通过Pandas读取大文件的实例
Jun 07 Python
浅谈python中拼接路径os.path.join斜杠的问题
Oct 23 Python
python3.7 sys模块的具体使用
Jul 22 Python
Python使用指定字符长度切分数据示例
Dec 05 Python
Python PyQt5模块实现窗口GUI界面代码实例
May 12 Python
如何在VSCode下使用Jupyter的教程详解
Jul 13 Python
Python getattr()函数使用方法代码实例
Aug 10 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
WHOIS类的修改版
2006/10/09 PHP
一步一步学习PHP(7) php 字符串相关应用
2010/03/05 PHP
php实现文本数据导入SQL SERVER
2015/05/17 PHP
JS控制表格隔行变色
2006/06/26 Javascript
使用IE的地址栏来辅助调试Web页脚本
2007/03/08 Javascript
jquery使用jquery.zclip插件复制对象的实例教程
2013/12/04 Javascript
js 立即调用的函数表达式如何写
2014/01/12 Javascript
15个值得开发人员关注的jQuery开发技巧和心得总结【经典收藏】
2016/05/25 Javascript
js倒计时简单实现代码
2016/08/11 Javascript
浅谈javascript中遇到的字符串对象处理
2016/11/18 Javascript
Node.js测试中的Mock文件系统详解
2016/11/21 Javascript
bootstrap模态框消失问题的解决方法
2016/12/02 Javascript
js编写三级联动简单案例
2016/12/21 Javascript
Nodejs中Express 常用中间件 body-parser 实现解析
2017/05/22 NodeJs
node.js操作mongodb简单示例分享
2017/05/25 Javascript
Three.js基础学习教程
2017/11/16 Javascript
JS/HTML5游戏常用算法之追踪算法实例详解
2018/12/12 Javascript
新手如何快速理解js异步编程
2019/06/24 Javascript
Vue表单控件数据绑定方法详解
2020/02/05 Javascript
基于wxpython实现的windows GUI程序实例
2015/05/30 Python
对Python闭包与延迟绑定的方法详解
2019/01/07 Python
python hashlib加密实现代码
2019/10/17 Python
python 实现绘制整齐的表格
2019/11/18 Python
python  ceiling divide 除法向上取整(或小数向上取整)的实例
2019/12/27 Python
tensorflow 获取checkpoint中的变量列表实例
2020/02/11 Python
解决python -m pip install --upgrade pip 升级不成功问题
2020/03/05 Python
Django之富文本(获取内容,设置内容方式)
2020/05/21 Python
给女儿的表扬信
2014/01/18 职场文书
家具促销活动方案
2014/02/16 职场文书
中学生学雷锋演讲稿
2014/04/26 职场文书
大学专科自荐信
2014/06/17 职场文书
高三语文复习计划
2015/01/19 职场文书
捐书活动倡议书
2015/04/27 职场文书
CSS中em的正确打开方式详解
2021/04/08 HTML / CSS
基于Golang 高并发问题的解决方案
2021/05/08 Golang
浅谈pytorch中stack和cat的及to_tensor的坑
2021/05/20 Python