python之鸭子类型
python不支持多态,也不用支持多态,python是一种多态语言,崇尚鸭子类型。
在程序设计中,鸭子类型是动态类型的一种风格,不是由继承特定的类或实现特定的接口,而是当前的方法和属性的集合决定,鸭子类型中关注的不是对象的类型本身,而是他如何使用。
这个概念的名字来源于由James Whitcomb Riley提出的鸭子测试,“鸭子测试”可以这样表述:“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”
我们可以这样理解:在不使用鸭子类型的语言中,我们可以编写一个函数,它接受一个类型为鸭的对象,并调用它的走和叫方法。在使用鸭子类型的语言中,这样的一个函数可以接受一个任意类型的对象,并调用它的走和叫方法。也许你对这段话还不理解,那么请看下面的例子:
>>> class duck(): #duck类型
def walk(self):
print('i am a duck,and i can walk')
def swim(self):
print('i am a duck,and i can swim')
>>> class cat(): #cat类型
def walk(self):
print('i am a cat,and i can walk')
def swim(self):
print('i am a cat,and i can swim')
实现一个动物walk和swim的功能函数:
>>> def walk_swim(animal):
animal.walk()
animal.swim()
创建对象以及调用walk_swim函数:
>>> d=duck()
>>> c=cat()
>>> walk_swim(d)
i am a duck,and i can walk
i am a duck,and i can swim
>>> walk_swim(c)
i am a cat,and i can walk
i am a cat,and i can swim
函数walk_swim的参数animal是任意类型,它可以接收任意类型的参数,当传入duck的对象d的时候,它会直接调用对象里面的walk和swim方法,如果对象里面没有该功能的方法,则会报错。
在python把上述代码的实现方法叫做protocol(协议),这些protocol可以看作是通知型的接口,它规定了调用方使用该功能要调用对象的哪些方法,被调用方要实现哪些方法才能完成这个功能。它和java中的接口区别在于java中的接口功能实现需要通过继承,继承的类必须实现接口中的所有的抽象方法,所以在Java中强调的是类型的概念,而python中的protocol更多的是通知性的,一个函数规定要实现某个功能需要调用传入对象的哪些方法,所有实现这些方法的类就可以实现这个功能
具体从上面两个类来说,第一个类实现了__getitem__方法,那python的解释器就会把它当做一个collection,就可以在这个类的对象上使用切片,获取子项等方法,第二个类实现了__iter__和next方法,python就会认为它是一个iterator,就可以在这个类的对象上通过循环来获取各个子项。一个类可以实现它有能力实现的方法,并只能被用于在它有意义的情况下。
这两个类和上面的鸭子类相比较,其实用于切边的和用于循环的iter()就相当于watch_duck函数,这些函数都接收任意类的对象,并调用实现功能所需要的对象中的方法来实现功能,若该函数中调用的方法对象里面不存在,就报错。
从上面可以看出,python鸭子类型的灵活性在于它关注的是这个所调用的对象是如何被使用的,而没有关注对象类型的本身是什么。所以在python中使用isinstance来判断传入参数的类型是不提倡的,更pythonic的方法是直接使用传入的参数,通过try,except来处理传入参数不符合要求的情况。我们应该通过传入对象的能力而不是传入对象的类型来使用该对象
python之鸭子类型的更多相关文章
- python与鸭子类型
部分参考来源:作者:JasonDing https://www.jianshu.com/p/650485b78d11##s1 首先介绍下面向对象(OOP)的三大特征: (1)面向对象程序设计有三大特 ...
- python 全栈开发,Day21(抽象类,接口类,多态,鸭子类型)
一.昨日复习 派生方法和派生属性 super 只有在子父类拥有同名方法的时候, 想使用子类的对象调用父类的方法时,才使用super super在类内 : super().方法名(arg1,..) 指名 ...
- python多态和鸭子类型
多态与多态性 多态指的是一类事物有多种形态,(一个抽象类有多个子类,因而多态的概念依赖于继承). 比如:文件分为文本文件,可执行文件(在定义角度) 比如 我们按下 F1 键这个动作: 如果当前在 Fl ...
- python语言的鸭子类型和强类型语言的多态
python语言的鸭子类型和强类型语言的多态 前面讲接口类的时候举过一个有关支付方式的例子,支付方式可以有几种,微信支付,支付宝支付,苹果支付等,这几个不同的支付都统一于支付,像这样几个类都统一于 某 ...
- python鸭子类型
“当看到一只鸟走起来像鸭子.游泳起来像鸭子.叫起来也像鸭子,那么这只鸟就能够被称为鸭子” python的鸭子类型的设计让python的诸多对象的分类和应用更加灵活,需要注意类型和对象的区别(pytho ...
- 面向对象相关概念与在python中的面向对象知识(魔法方法+反射+元类+鸭子类型)
面向对象知识 封装 封装的原理是,其成员变量代表对象的属性,方法代表这个对象的动作真正的封装是,经过深入的思考,做出良好的抽象(设计属性时用到),给出“完整且最小”的接口,并使得内部细节可以对外透明( ...
- Python面向对象04 /封装、多态、鸭子类型、类的约束、super
Python面向对象04 /封装.多态.鸭子类型.类的约束.super 目录 Python面向对象04 /封装.多态.鸭子类型.类的约束.super 1. 封装 2. 多态 3. 鸭子类型 4. 类的 ...
- python 面向对象专题(四):封装、多态、鸭子类型、类的约束、super
https://www.cnblogs.com/liubing8/p/11321099.html 目录 Python面向对象04 /封装.多态.鸭子类型.类的约束.super 1. 封装 2. 多态 ...
- 多态 鸭子类型 反射 内置方法(__str__,__del__) 异常处理
''' 1什么是多态 多态指的是同一种/类事物的不同形态 2 为何要有多态 多态性:在多态的背景下,可以在不用考虑对象具体类型的前提下而直接使用对象 多态性的精髓:统一 多态性的好处: 1增加了程序的 ...
随机推荐
- win10下通过Anaconda安装TensorFlow-GPU1.3版本,并配置pycharm运行Mnist手写识别程序
折腾了一天半终于装好了win10下的TensorFlow-GPU版,在这里做个记录. 准备安装包: visual studio 2015: Anaconda3-4.2.0-Windows-x86_64 ...
- (五)bootloader 启动 ucore os
Lab1 : bootloader 启动 ucore os 一.内容提要 x86启动顺序 C函数调用 gcc内联汇编(inline assembly) x86-32下的中断处理 小结 二.x86启动顺 ...
- Css3实现常用的几种loading动画
css实现loading动画非常方便,也非常实用 第一种 <!DOCTYPE html> <html lang="en"> <head> < ...
- Maven 手动添加第三方依赖包及编译打包和java命令行编译JAVA文件并使用jar命令打包
一,实例:新建了一个Maven项目,在eclipse中通过 build path –> configure path-.将依赖包添加到工程中后,eclipse不报错了.但是用Maven命令 mv ...
- python自带的调试器
python是自带调试器的. 比如你写了一个python程序,名叫test.py. 你想调试一下这个程序,你可以执行 python -m pdb test.py,就会进入test.py的调试. 想查看 ...
- WINFROM窗体实现圆角
首先我们先看看效果图 接下来我们看看怎么实现 先把窗体的FromBorderStyle属性改成None. 接下来登录窗体代码代码: 添加一个窗体Paint事件,引用using System.Drawi ...
- apache - http
apahce 添加模块编译 httpd # so模块用来提供DSO支持的apache核心模块 # 如果编译中包含任何DSO模块,则mod_so会被自动包含进核心. # 如果希望核心能够装载DSO, ...
- mysql 查询优化 ~explain解读之extra解读
一 explain 常用状态 1 using filesort 常见于order by 字段 无法走索引造成,文件排序.需要注意优化,复杂条件可以选择建立联合索引进行优化2 using join bu ...
- TDateTimePicker 选择最小日期时异常处理
TDateTimePicker 控件属性窗体选择最小日期,运行时选择时可以看到的最小的日期,但是选择最小时就异常 :date is less than minimum of *** 解决过程 ...
- python cookbook 笔记二
去重和排序: #coding=utf-8 def dedupe(items): seen = set() for item in items: if item not in seen: yield i ...