python 鸭子类型
首先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鸭子类型
“当看到一只鸟走起来像鸭子.游泳起来像鸭子.叫起来也像鸭子,那么这只鸟就能够被称为鸭子” python的鸭子类型的设计让python的诸多对象的分类和应用更加灵活,需要注意类型和对象的区别(pytho ...
- Python鸭子类型思想
动态语言中经常提到鸭子类型,所谓鸭子类型就是:如果走起路来像鸭子,叫起来也像鸭子,那么它就是鸭子(If it walks like a duck and quacks like a duck, it ...
- python鸭子类型(duck type)
1.什么是鸭子类型顾名思义,就是看起来像鸭子的类型,就可以叫做鸭子类型所以,鸭子类型是一种不严格的类型,弱类型有相同方法的类型,可以归为一类鸭子.2.鸭子类型示例 class dog: def run ...
- python之鸭子类型
python不支持多态,也不用支持多态,python是一种多态语言,崇尚鸭子类型. 在程序设计中,鸭子类型是动态类型的一种风格,不是由继承特定的类或实现特定的接口,而是当前的方法和属性的集合决定,鸭子 ...
- python之类的多态(鸭子类型 )、封装和内置函数property
一.多态 1.什么是多态:一个类表现出的多种状态--->通过继承来实现的例如:class Animal:passclass Dog(Animal):passclass Cat(Animal):p ...
- python 全栈开发,Day21(抽象类,接口类,多态,鸭子类型)
一.昨日复习 派生方法和派生属性 super 只有在子父类拥有同名方法的时候, 想使用子类的对象调用父类的方法时,才使用super super在类内 : super().方法名(arg1,..) 指名 ...
- [py]python多态-动态语言的鸭子类型
弱类型?强类型?动态语言,静态语言 弱类型: 在程序运行过程中,类型可变 还有一种说法: 动态 variables must necessarily be defined before they ar ...
- python多态和鸭子类型
多态与多态性 多态指的是一类事物有多种形态,(一个抽象类有多个子类,因而多态的概念依赖于继承). 比如:文件分为文本文件,可执行文件(在定义角度) 比如 我们按下 F1 键这个动作: 如果当前在 Fl ...
- Python多态、鸭子类型
一.多态 多态指的是一类事物有多种形态. 动物有多种形态:人,狗,猪 import abc class Animal(metaclass=abc.ABCMeta): #同一类事物:动物 @abc.ab ...
随机推荐
- es6学习笔记--字符串&数值&数组&函数&对象的扩展
这几天抽空学习了es6语法,关于字符串,数值,数组,函数以及对象的扩展,看到es6标准入门这本书,里面讲的扩展特别多,我认为有几部分在项目上用不到,就挑有用的当笔记学习了. 字符串的扩展 str.in ...
- 依赖反转原则DIP 与 asp.net core 项目结构
DIP 依赖反转原则 Dependency Inversion Principle 的定义如下: 高级别的模块不应该依赖于低级别的模块, 他们都应该依赖于抽象. 假设Controller依赖于Repo ...
- 学习笔记-Little Tips_day20170615-"\n" and '\n'
1.'\n'是字符 相当于char 占一个字节 "\n"是字符串 相当于char[2] 占两个字节 答案是ABC
- 颜色的RGB值表示法
颜色的RGB值表示法 从物理光学试验中得出:红.绿.蓝三种色光是其他色光所混合不出来的.而这三种色光以不同比例的混合几乎可以得出自然界所有的颜色. 如红光与不同比例的绿光混合可以得出橙.黄.黄绿等色: ...
- java web 项目中获取当前路径的几种方法
1.jsp中取得路径: 以工程名为TEST为例: (1)得到包含工程名的当前页面全路径:request.getRequestURI() 结果:/TEST/test.jsp (2)得到工程名:req ...
- python作业02
1.请用代码实现:利用下划线将列表的每一个元素拼接成字符串,li=['alex', 'eric', 'rain'] li = ['alex', 'eric', 'rain'] v = "_& ...
- c++ --> 你可能不知道的c++
你可能不知道的c++ 你可能不知道的 C++(一) 你可能不知道的 C++(二)
- 通过jersey-client客户端调用Jersey的Web服务模拟CURD
一.总体说明 通过jersey-client接口,创建客户端程序,来调用Jersey实现的RESTful服务,实现增.删.改.查等操作. 服务端主要是通过内存的方式,来模拟用户的增加.删除.修改.查询 ...
- (译文)开始学习Vue——构建你的第一个Vue应用
我们要构建如下组件:(最终代码在这里:https://codesandbox.io/s/38k1y8x375) 开始 Vue是支持单文件组件的,但是我们不准备这么做.你也可以构建一个全局的组件,通过V ...
- JavaScript(第二十九天)【js处理XML】
随着互联网的发展,Web应用程序的丰富,开发人员越来越希望能够使用客户端来操作XML技术.而XML技术一度成为存储和传输结构化数据的标准.所以,本章就详细探讨一下JavaScript中使用XML的技术 ...