程序设计中,鸭子类型英语duck typing)是动态类型的一种风格。在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由当前方法和属性的集合决定。这个概念的名字来源于由James Whitcomb Riley提出的鸭子测试(见下面的“历史”章节),“鸭子测试”可以这样表述:

“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”[1][2]

在鸭子类型中,关注的不是对象的类型本身,而是它是如何使用的。例如,在不使用鸭子类型的语言中,我们可以编写一个函数,它接受一个类型为的对象,并调用它的方法。在使用鸭子类型的语言中,这样的一个函数可以接受一个任意类型的对象,并调用它的方法。如果这些需要被调用的方法不存在,那么将引发一个运行时错误。任何拥有这样的正确的方法的对象都可被函数接受的这种行为引出了以上表述,这种决定类型的方式因此得名。

鸭子类型在Python中被广泛使用。Python术语表这样定义鸭子类型:

Pythonic programming style that determines an object's type by inspection of its method or attribute signature rather than by explicit relationship to some type object ("If it looks like a duck and quacks like a duck, it must be a duck.") By emphasizing interfaces rather than specific types, well-designed code improves its flexibility by allowing polymorphic substitution. Duck-typing avoids tests using type() orisinstance(). Instead, it typically employs the EAFP (Easier to Ask Forgiveness than Permission) style of programming.

在Python中,鸭子类型的最典型例子就是类似file的类。这些类可以实现file的一些或全部方法,并可以用于file通常使用的地方。例如,GzipFile实现了一个用于访问gzip压缩的数据的类似file的对象。cStringIO允许把一个Python字符串视作一个文件。套接字(socket)也和文件共同拥有许多相同的方法。然而套接字缺少tell()方法,不能用于GzipFile可以使用的所有地方。这体现了鸭子类型的可伸缩性:一个类似file的对象可以实现它有能力实现的方法,且只能被用于它有意义的情形下。

EAFP原则描述了异常处理的使用。例如相对于检查一个自称为类似Duck的对象是否拥有一个quack()方法(使用if hasattr(mallard, "quack"): ...),人们通常更倾向于用异常处理把对quack的调用尝试包裹起来:

try:
mallard.quack()
except (AttributeError, TypeError):
print "mallard can't quack()"

这个写法的优势在于它鼓励结构化处理其他来自类的错误(这样的话,例如,一个不能完成quack的Duck子类可以抛出一个“QuackException”,这个异常可以简单地添加到包裹它的代码,并不需要影响更多的代码的逻辑。同时,对于其他不同类的对象存在不兼容的成员而造成的命名冲突,它也能够处理(例如,假设有一个医学专家Mallard有一个布尔属性将他分类为“quack=True”,试图执行Mallard.quack()将抛出一个TypeError)。

在更实际的实现类似file的行为的例子中,人们更倾向于使用Python的异常处理机制来处理各种各样的可能因为各种程序员无法控制的环境和operating system问题而发生的I/O错误。在这里,“鸭子类型”产生的异常可以在它们自己的子句中捕获,与操作系统、I/O和其他可能的错误分别处理,从而避开复杂的检测和错误检查逻辑。

参考:http://zh.wikipedia.org/wiki/%E9%B8%AD%E5%AD%90%E7%B1%BB%E5%9E%8B

duck type鸭子类型的更多相关文章

  1. 类型检查和鸭子类型 Duck typing in computer programming is an application of the duck test 鸭子测试 鸭子类型 指示编译器将类的类型检查安排在运行时而不是编译时 type checking can be specified to occur at run time rather than compile time.

    Go所提供的面向对象功能十分简洁,但却兼具了类型检查和鸭子类型两者的有点,这是何等优秀的设计啊! Duck typing in computer programming is an applicati ...

  2. 鸭子类型 - Duck Typing

    还是先看定义 duck typing, 鸭子类型是多态(polymorphism)的一种形式.在这种形式中,不管对象属于哪个, 也不管声明的具体接口是什么,只要对象实现了相应的方法,函数就可以在对象上 ...

  3. js设计模式--鸭子类型

    1.简介 JavaScript没有提供传统面向对象语言的类式继承通过原型委托的形式实现对象与对象之间的继承没有对抽象类和接口的支持 编程语言按数据类型可分为静态类型语言和动态类型语言 变量的类型要到程 ...

  4. python鸭子类型(duck type)

    1.什么是鸭子类型顾名思义,就是看起来像鸭子的类型,就可以叫做鸭子类型所以,鸭子类型是一种不严格的类型,弱类型有相同方法的类型,可以归为一类鸭子.2.鸭子类型示例 class dog: def run ...

  5. 什么是“鸭子类型(duck typing)”?

    在计算机编程世界里会接触到一个知识点 —— duck typing,叫“鸭子类型”.   它有一个形象的解释: “当看到一只鸟走起来像鸭子.游泳起来像鸭子.叫起来也像鸭子,那么这只鸟就可以被称为鸭子. ...

  6. 鸭子类型duck typing(动态)

    在程序设计中,鸭子类型(duck typing)是动态类型的一种风格.在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由当前方法和属性的集合决定.这个概念的名字来源于由Ja ...

  7. 鸭子类型(Duck Typing)

    鸭子类型(Duck Typing) 动态类型.没有类型检验.不关注类型,关注方法 相当于静态类型语言的多态 这是程序设计中的一种类型推断风格,这种风格适用于动态语言(比如PHP.Python.Ruby ...

  8. 什么是鸭子类型(duck typing)

    "当看到一仅仅鸟走起来像鸭子.游泳起来像鸭子.叫起来也像鸭子,那么这仅仅鸟就能够被称为鸭子." 我们并不关心对象是什么类型,究竟是不是鸭子,仅仅关心行为. 比方在python中.有 ...

  9. 到底啥是鸭子类型(duck typing)带简单例子

    #百度百科鸭子类型定义 这是程序设计中的一种类型推断风格,这种风格适用于动态语言(比如PHP.Python.Ruby.Typescript.Perl.Objective-C.Lua.Julia.Jav ...

随机推荐

  1. 关于js中return false、event.preventDefault()和event.stopPropagation()

    在平时项目中,如果遇到需要阻止浏览器默认行为,大家经常会用return false;和event.preventDefault()来阻止,但对它俩的区别还是有些一知半解,于是看了文档,查了些资料,在此 ...

  2. Windows Server 2008中关闭事件跟踪程序的方法

    Windows Server 2008跟Windows Server 2003一样,在关机的时候会弹出一个“关闭事件跟踪程序”窗口,当然微软这么做是处于安全的考虑啦,但是如果我们只是个人用用的话,那就 ...

  3. PHP 数组的值插入

    曾今写过一个坑货的数组方法 function array_insert($myarray,$value,$position=0) {    $fore=($position==0)?array():a ...

  4. Asp.net Mvc对比Php的4大误解

    一:asp.net技术已过时,Php技术更新 Asp.net mvc 5 发布于2014 夏天. 二:php开发者更多,所以更能得到帮助 2者对比犹如下图,会拿电锯的肯定多少会点锯子, 会用锯子的不一 ...

  5. javascript 动态操作Html

    <html> <body> <p>aaaaa</p> <input type="button" value="con ...

  6. 在.Net中进行跨线程的控件操作(上篇:Control.Invoke)

    本文的重点在于介绍如何在多线程编程中,从非UI线程上访问界面中的控件.有过多线程编程经验的人都知道,当我们在非UI线程上试图给一个界面中的控件赋值的时候,比如说label的Text属性,系统会抛出一个 ...

  7. 前端--json数据的处理及相关兼容问题

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,是理想的数据交换格式.同时,JSON是 JavaScript 原生格式,这意 ...

  8. Maven项目的目录结构

    刚接触Maven没多长时间,实习时在的小公司很不规范,所有web项目都是dynamic web project搭建,没有用到项目构建,管理工具,导致了非常多的重复工作与低效. 先来看看Maven的功能 ...

  9. yii2源码学习笔记(八)

    Action是所有控制器的基类,接下来了解一下它的源码.yii2\base\Action.php <?php /** * @link http://www.yiiframework.com/ * ...

  10. PHP使用DES进行加密解密

    DES是一种对称加密算法,也就是通过密文和合法的密钥能够将明文还原出来,在程序开发过程中有些 接口可能需要获取原始数据,而发送的数据又比较敏感(比如用户的密码等信息),这时可以选择DES加密算法,DE ...