今天来聊聊编程语言中的动态类型语言和duck类型,维基百科对动态语言的定义:动态编程语言是一类结构可以在运行时改变的语言:例如New可以引入功能、对象甚至代码,可以删除现有功能或进行其他结构更改。动态语言目前非常动态。比如PHP、Ruby、Python都是动态语言,而C、C++、Java等语言则不是动态语言。这个解释很抽象。实际上,动态语言是相对于静态语言而言的。静态语言的特点是,在程序执行之前编译代码时,一切都可以从代码中得知,比如变量的类型,方法的返回值类型:Strings="hello"s="world"s=1//编译时会报错在静态语言中,变量是有类型信息的,是一块内存区域。静态语言的优点是代码结构非常规范,易于调试,但有时显得啰嗦。然而,动态语言在程序运行之前并不是什么都知道。变量(严格来说叫名字,就像人名一样)不需要指定类型。变量本身没有任何类型信息。类型信息是在对象上的,对象是什么类型,你要等到程序运行起来才知道,动态类型语言的好处是读起来方便,不需要写很多类型-相关代码;缺点是不方便调试,命名不规范会造成看不懂,不利于理解。s="hello"s="world"s=1#可以随意给变量赋值,不管是什么类型。Duck类型在动态语言中经常被提及。所谓鸭型就是:Ifyouwalklikeaduck,Ifitquackinglikeaduck,thenitisaduck(Ifitwalkslikeaduckandquackinglikeaduck,itmustbeaduck)。Ducktyping是编程语言中动态类型语言中的一种设计风格。对象的特性不是由父类决定的,而是由对象的方法决定的。如果你正在学习Java或C++等静态语言,你可能对ducktyping没有很深的理解,因为静态语言中对象的特性取决于它的父类。但是动态语言不同,比如迭代器,任何实现了__iter__和__next__方法的对象都可以称为迭代器,但是对象本身的类型不受限制,可以自定义为任意类#python3classFoo:def__iter__(self):passdef__next__(self):passfromcollectionsimportIterablefromcollectionsimportIteratorprint(isinstance(Foo(),Iterable))#Trueprint(isinstance(Foo(),Iterator))#True我们不需要继承Iterator来实现迭代器的功能。当一个函数期望接收一个Iterator类型的参数,但是我们传递的是一个Foo的实例对象,其实是可以的。如果换成Java等静态语言,则必须通过Iterator或其子类。鸭子类型通常受益于“不”测试方法和函数中的参数类型,而是依靠文档、干净的代码和测试来确保正确使用。这既是优势也是劣势。缺点是需要通过文档知道参数类型。为了弥补这个不足,Python3.6引入了类型信息,可以在定义变量的时候指定类型。例如,下面的函数表示它接收一个str类型的参数。并返回一个str类型的值:【本文为专栏作家“刘志军”原创文章,作者微信公众号:Python之禅(VTtalk)】点此阅读作者更多好文
