详解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写入xml文件的方法
May 08 Python
Python 探针的实现原理
Apr 23 Python
使用python为mysql实现restful接口
Jan 05 Python
python使用MQTT给硬件传输图片的实现方法
May 05 Python
详解Matplotlib绘图之属性设置
Aug 23 Python
YUV转为jpg图像的实现
Dec 09 Python
使用 pytorch 创建神经网络拟合sin函数的实现
Feb 24 Python
python由已知数组快速生成新数组的方法
Apr 08 Python
TensorFlow实现批量归一化操作的示例
Apr 22 Python
pycharm 多行批量缩进和反向缩进快捷键介绍
Jan 15 Python
Linux系统下升级pip的完整步骤
Jan 31 Python
python爬虫scrapy基于CrawlSpider类的全站数据爬取示例解析
Feb 20 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
《OVERLORD》第四季,终于等到你!
2020/03/02 日漫
php 服务器调试 Zend Debugger 的安装教程
2009/09/25 PHP
js克隆对象、数组的常用方法介绍
2013/09/26 Javascript
jQuery中removeClass()方法用法实例
2015/01/05 Javascript
js数组去重的5种算法实现
2015/11/04 Javascript
JS组件Bootstrap Select2使用方法详解
2020/04/17 Javascript
JavaScript面向对象编写购物车功能
2016/08/19 Javascript
前端弹出对话框 js实现ajax交互
2016/09/09 Javascript
为你的微信小程序体积瘦身详解
2017/05/20 Javascript
mongoose中利用populate处理嵌套的方法
2017/05/26 Javascript
jQuery查找和过滤_动力节点节点Java学院整理
2017/07/04 jQuery
基于jQuery实现无缝轮播与左右点击效果
2018/05/13 jQuery
vue + node如何通过一个Txt文件批量生成MP3并压缩成Zip
2020/06/02 Javascript
vue中echarts引入中国地图的案例
2020/07/28 Javascript
vue项目中openlayers绘制行政区划
2020/12/24 Vue.js
python 解析html之BeautifulSoup
2009/07/07 Python
定制FileField中的上传文件名称实例
2017/08/23 Python
Python eval的常见错误封装及利用原理详解
2019/03/26 Python
Python Pandas分组聚合的实现方法
2019/07/02 Python
Python Opencv任意形状目标检测并绘制框图
2019/07/23 Python
python读取word 中指定位置的表格及表格数据
2019/10/23 Python
keras获得model中某一层的某一个Tensor的输出维度教程
2020/01/24 Python
Python flask框架实现查询数据库并显示数据
2020/06/04 Python
python学习笔记之多进程
2020/08/06 Python
python中绕过反爬虫的方法总结
2020/11/25 Python
使用Python爬虫爬取小红书完完整整的全过程
2021/01/19 Python
时尚的CSS3进度条效果
2012/02/22 HTML / CSS
TUMI新加坡官网:国际领先的商旅箱包品牌
2019/01/12 全球购物
毕业生文员求职信
2013/11/03 职场文书
企划主管岗位职责
2013/12/12 职场文书
关于拾金不昧的感谢信
2015/01/21 职场文书
首都博物馆观后感
2015/06/05 职场文书
篮球赛闭幕式主持词
2015/07/03 职场文书
教师教育教学随笔
2015/08/15 职场文书
go开发alertmanger实现钉钉报警
2021/07/16 Golang
Java 通过手写分布式雪花SnowFlake生成ID方法详解
2022/04/07 Java/Android