文档章节

鸭子类型

吃一堑消化不良
 吃一堑消化不良
发布于 2016/12/14 19:46
字数 622
阅读 24
收藏 0

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

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

        例如,在不使用鸭子类型的语言中,我们可以编写一个函数,它接受一个类型为"鸭子"的对象,并调用它的"走"和"叫"方法。在使用鸭子类型的语言中,这样的一个函数可以接受一个任意类型的对象,并调用它的"走"和"叫"方法。如果这些需要被调用的方法不存在,那么将引发一个运行时错误。任何拥有这样的正确的"走"和"叫"方法的对象都可被函数接受。

        下面以Python为例,我们定义三个类,并这3个类的实例将作为参数传到一个函数中:

class Have_value(object):
    def __init__(self):
        self.value = 10

class Have_morethanvalue(object):
    def __init__(self):
        self.value = 11
        self.more = "more"
class Not_havevalue(object):
    def __init__(self):
        self.more = "more"

def print_value(x):
    print(x.value)

print_value(a)
print_value(b)
print_value(c)

         输出如下:

10
11
AttributeError Traceback (most recent call last)
in <module>() print_value(c)
in print_value(x)
def print_value(x):
print(x.value)
AttributeError: 'Not_havevalue' object has no attribute 'value'

        函数只管它找他要的字段(变量或方法名),有就算对,没有就算错,即只要可以执行就不算错

        再看一个例子:

class V:
    def __init__(self,x,y):
        self.x = x
        self.y = y
    def __repr__(self):
        return str(self.x)+","+str(self.y)
    def __add__(self,other):
        result = V(self.x+other.x,self.y+other.y)
        return result

class C:
    def __init__(self,x,y,z):
        self.x = x
        self.y = y
        self.z = z
    def __repr__(self):
        return str(self.x)+","+str(self.y)+","+str(self.z)
    def __add__(self,other):
        result = C(self.x+other.x,self.y+other.y,other.z)
        return result

c = C(1,2,4)
v = V(3,5)
print(v+c) #4,7
print(c+v) #会报错

        输出如下:

4,7
AttributeError  Traceback (most recent call last)
in <module>()
print(v+c) #4,7
print(c+v) #会报错
in __add__(self, other)
return str(self.x)+","+str(self.y)+","+str(self.z)
def __add__(self,other):
result = C(self.x+other.x,self.y+other.y,other.z)
return result
AttributeError: 'V' object has no attribute 'z'

        这个例子可以看出,v+c被执行了,因为v的__add__()方法可以执行,而c+v就会报错,因为c的__add__方法中需要传入的参数有z这个字段,而v中没有.

本文转载自:https://hsz1273327.gitbooks.io/python_total_tutorial/content/Python_Advance/%E9%9D%A2%E5%90%91%E5%AF

共有 人打赏支持
吃一堑消化不良
粉丝 28
博文 188
码字总数 112947
作品 0
浦东
程序员
私信 提问
策略者模式

1.什么是策略模式? 定义算法族,将他们封装其起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户 2.什么情况下使用策略模式? 实现某一个功能有多条途径,每一条途径对...

J星星点灯
2017/12/02
0
0
Python—duck type鸭子类型

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

qq_39521554
2018/04/20
0
0
语言设计中的鸭子类型风格

在动态语言的世界里一直流传着一种叫做鸭子类型的风格,其来自谚语:“如果行鸭子一样走路,像鸭子一样呱呱叫,那它就是一只鸭子”。 从鸭子类型,我们可以联想到它的推导,并不在乎类型的真...

justjavac
2013/07/04
281
0
python常用的一些技巧

1、三目操作符 2、鸭子类型(duck typing) 首先Python不支持多态,也不用支持多态,python是一种多态语言,崇尚鸭子类型。以下是维基百科中对鸭子类型得论述: 在程序设计中,鸭子类型(英语...

铁扇公主1
2017/05/20
53
0
java中接口和抽象类的区别

1.抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的 2.抽象类中的方法可以是抽象的,也可以是非抽象的,接口中的方法都是抽象的; 3.抽象类可以有静...

正阳Android
2018/01/25
0
0

没有更多内容

加载失败,请刷新页面

加载更多

关于C++ 容器的swap操作

一、swap操作交换两个相同类型的容器的内容,一般的容器(除array外),交换两个容器内容的操作会保证非常快,因为并没有交换元素本身,而只是交换了两个容器的内部数据结构。 拿vector做个例...

shzwork
12分钟前
0
0
程序员从宏观、微观角度浅析JVM虚拟机!

1.问题 1、JAVA文本文件如何被翻译成CLASS二进制文件? 2、如何理解CLASS文件的组成结构? 3、虚拟机如何加载使用类文件的生命周期? 4、虚拟机系列诊断工具如何使用? 5、虚拟机内存淘汰机制?...

我最喜欢三大框架
13分钟前
1
0
Choerodon猪齿鱼实践之应用生命周期管理

Choerodon平台中的开发和部署都是围绕应用来进行的,那Choerodon平台中的应用有什么样的特性?又是怎样来进行管理的呢?本文旨在深入地介绍Choerodon平台中应用的功能特性及其生命周期的管理...

Choerodon
34分钟前
0
0
Websocket之Jmeter压力测试

最近使用到Websocket进行聊天功能开发,用Jmeter进行压力测试,记录下。 使用的Jmeter版本5.1.1,自行从apache jmeter官网下载。 首先要添加Websocket的插件,网上有很多,我从百度网盘下载的...

克虏伯
34分钟前
0
0
作为Java程序员这些技术都不会,拿什么去涨薪跳槽?

引言 当下,正面临着近几年来的最严重的互联网寒冬,听得最多的一句话便是:相见于江湖~,缩减HC、裁员不绝于耳,大家都是人心惶惶,年前如此,年后想必肯定又是一场更为惨烈的江湖厮杀。但博...

别打我会飞
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部