通过案例解析python鸭子类型相关原理


Posted in Python onOctober 10, 2020

首先Python不支持多态,也不用支持多态,python是一种多态语言,崇尚鸭子类型。

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

“鸭子测试”可以这样表述:

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

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

鸭子类型通常得益于不测试方法和函数中参数的类型,而是依赖文档、清晰的代码和测试来确保正确使用。从静态类型语言转向动态类型语言的用户通常试图添加一些静态的(在运行之前的)类型检查,从而影响了鸭子类型的益处和可伸缩性,并约束了语言的动态特性。

-------------------------------------------

毫无疑问在python中对象也是一块内存,内存中除了包含属性、方法之外,还包含了对象得类型,我们通过引用来访问对象,比如a=A(),首先python创建一个对象A,然后声明一个变量a,再将变量a与对象A联系起来。变量a是没有类型得,它的类型取决于其关联的对象。a=A()时,a是一个A类型的引用,我们可以说a是A类型的,如果再将a赋值3,a=3,此时a就是一个整型的引用,但python并不是弱类型语言,在python中'2'+3会报错,而在php中'2'+3会得到5。可以这么理解,在python中变量类似与c中的指针,和c不同的是python中的变量可以指向任何类型,虽然这么说不太准确,但是理解起来容易点。

因此,在python运行过程中,参数被传递过来之前并不知道参数的类型,虽然python中的方法也是后期绑定,但是和java中多态的后期绑定却是不同的,java中的后期绑定至少知道对象的类型,而python中就不知道参数的类型。

还引用上次的例子:

class A:  
  def prt(self):  
    print "A"  
  
class B(A):  
  def prt(self):  
    print "B"  
      
class C(A):  
  def prt(self):  
    print "C"  
      
class D(A):  
  pass  
  
class E:  
  def prt(self):  
    print "E"  
  
class F:  
  pass  
  
def test(arg):  
  arg.prt()  
  
a = A()  
b = B()  
c = C()  
d = D()  
e = E()  
f = F()  
  
test(a)  
test(b)  
test(c)  
test(d)  
test(e)  
test(f)

输出结果:

A 
B 
C 
A 
E 
Traceback (most recent call last): 
 File "/Users/shikefu678/Documents/Aptana Studio 3 Workspace/demo/demo.py", line 33, in <module> 
  test(a),test(b),test(c),test(d),test(e),test(f) 
 File "/Users/shikefu678/Documents/Aptana Studio 3 Workspace/demo/demo.py", line 24, in test 
  arg.prt() 
AttributeError: F instance has no attribute 'prt'

a,b,c,d都是A类型的变量,所以可以得到预期的效果(从java角度的预期),e并不是A类型的变量但是根据鸭子类型,走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子,e有prt方法,所以在test方法中e就是一个A类型的变量,f没有prt方法,所以f不是A类型的变量。

以上是从java的角度分析的,其实上边都是一派胡言,只是为了说明python中的运行方法。没有谁规定test方法是接收的参数是什么类型的。test方法只规定,接收一个参数,调用这个参数的prt方法。在运行的时候如果这个参数有prt方法,python就执行,如果没有,python就报错,因为abcde都有prt方法,而f没有,所以得到了上边得结果,这就是python的运行方式。

从学python有3个月了,虽然以前没有怎么好好学习过java,但是java方面的书看了不少很多思维方式都转变不过来,总是想用java的思维方式来思考python的问题,实际上那样只会南辕北辙,python中有太多的东西和java不一样,从里到外的不一样。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python调用C/C++动态链接库的方法详解
Jul 22 Python
Python 通过URL打开图片实例详解
Jun 01 Python
Python实现抓取网页生成Excel文件的方法示例
Aug 05 Python
把pandas转换int型为str型的方法
Jan 29 Python
关于python多重赋值的小问题
Apr 17 Python
python实现本地批量ping多个IP的方法示例
Aug 07 Python
使用Python制作缩放自如的圣诞老人(圣诞树)
Dec 25 Python
pytorch 实现tensor与numpy数组转换
Dec 27 Python
Python使用py2neo操作图数据库neo4j的方法详解
Jan 13 Python
从零开始的TensorFlow+VScode开发环境搭建的步骤(图文)
Aug 31 Python
Jupyter Notebook安装及使用方法解析
Nov 12 Python
python小技巧——将变量保存在本地及读取
Nov 13 Python
通过实例解析python subprocess模块原理及用法
Oct 10 #Python
如何使用python自带IDLE的几种方法
Oct 10 #Python
Python的3种运行方式:命令行窗口、Python解释器、IDLE的实现
Oct 10 #Python
python如何利用Mitmproxy抓包
Oct 10 #Python
python批量生成条形码的示例
Oct 10 #Python
python如何对链表操作
Oct 10 #Python
Python timeit模块原理及使用方法
Oct 10 #Python
You might like
PHP实现MVC开发得最简单的方法――模型
2007/04/10 PHP
使用PHP socke 向指定页面提交数据
2008/07/23 PHP
Linux下 php5 MySQL5 Apache2 phpMyAdmin ZendOptimizer安装与配置[图文]
2008/11/18 PHP
PHP字符串的编码问题的详细介绍
2013/04/27 PHP
用PHP实现浏览器点击下载TXT文档的方法详解
2013/06/02 PHP
PHP自动生成后台导航网址的最佳方法
2013/08/27 PHP
Zend Framework入门应用实例详解
2016/12/11 PHP
javascript同步Import,同步调用外部js的方法
2008/07/08 Javascript
javascript正则表达式参数/g与/i及/gi的使用指南
2014/08/27 Javascript
JS实现一个列表中包含上移下移删除等功能
2014/09/24 Javascript
轻松创建nodejs服务器(7):阻塞操作的实现
2014/12/18 NodeJs
使用javascript实现Iframe自适应高度
2014/12/24 Javascript
javascript面向对象快速入门实例
2015/01/13 Javascript
jQuery实现表格展开与折叠的方法
2015/05/04 Javascript
深入理解React中es6创建组件this的方法
2016/08/29 Javascript
jquery控制页面的展开和隐藏实现方法(推荐)
2016/10/15 Javascript
AngularJS 获取ng-repeat动态生成的ng-model值实例详解
2016/11/29 Javascript
探讨跨域请求资源的几种方式(总结)
2016/12/02 Javascript
JS中如何实现复选框全选功能
2016/12/19 Javascript
基于jQuery实现火焰灯效果导航菜单
2017/01/04 Javascript
Javascript 一些需要注意的细节(必看篇)
2017/07/08 Javascript
基于LayUI分页和LayUI laypage分页的使用示例
2017/08/02 Javascript
解读ES6中class关键字
2017/11/20 Javascript
[01:14:34]DOTA2上海特级锦标赛C组资格赛#2 LGD VS Newbee第一局
2016/02/28 DOTA
[01:11:08]Winstrike vs NB 2018国际邀请赛淘汰赛BO1 8.21
2018/08/22 DOTA
[57:55]EG vs Fnatic 2018国际邀请赛小组赛BO2 第一场 8.19
2018/08/21 DOTA
Python json 错误xx is not JSON serializable解决办法
2017/03/15 Python
Python开发SQLite3数据库相关操作详解【连接,查询,插入,更新,删除,关闭等】
2017/07/27 Python
Python函数生成器原理及使用详解
2020/03/12 Python
python 图像插值 最近邻、双线性、双三次实例
2020/07/05 Python
时装界的“朋克之母”:Vivienne Westwood
2017/07/06 全球购物
学习方法演讲稿
2014/05/10 职场文书
求职自我推荐信
2014/06/25 职场文书
农林经济管理专业自荐信
2014/09/01 职场文书
戒赌保证书
2015/05/11 职场文书
教师师德工作总结2015
2015/07/22 职场文书