Python动态语言与鸭子类型详解

今天来说说编程语言中的动态类型语言与鸭子类型。

动态语言

维基百科对动态语言的定义:

动态编程语言是一类在运行时可以改变其结构的语言:例如新的函数、对象、甚至代码可以被引进,已有的函数可以被删除或是其他结构上的变化。动态语言目前非常具有活力如PHP、Ruby、Python 都属于动态语言,而C、C++、Java等语言则不属于动态语言。

这个解释很抽象,其实动态语言是相对静态语言而言的,静态语言的特点是在程序执行前,代码编译时从代码中就可以知道一切,比如变量的类型,方法的返回值类型:

String s = "hello"
s = "world"
s = 1 // 编译时就会报错

在静态语言中,变量有类型信息,它是一块内存区域,静态语言的优点是代码结构非常规范,便于调试,但有时显得啰嗦。而动态语言只有等到程序运行时才知道一切,变量(严格来说叫名字,就像人的名字一样)不需要指定类型,变量本身没有任何类型信息,类型信息在对象身上,对象是什么类型,必须等到程序运行时才知道,动态类型语言的优点在于方便阅读,不需要写很多类型相关的代码;缺点是不方便调试,命名不规范时会造成读不懂,不利于理解等。

s = "hello"
s = "world"
s = 1 # 可以给变量随意赋值,无论是什么类型都可以

鸭子类型

动态语言中经常提到鸭子类型,所谓鸭子类型就是:如果走起路来像鸭子,叫起来也像鸭子,那么它就是鸭子(If it walks like a duck and quacks like a duck, it must be a duck)。鸭子类型是编程语言中动态类型语言中的一种设计风格,一个对象的特征不是由父类决定,而是通过对象的方法决定的。

如果你学的是Java或者C++等静态语言,可能对鸭子类型的理解没那么深刻,因为静态语言中对象的特性取决于其父类。而动态语言则不一样,比如迭代器,任何实现了 __iter__ 和 __next__方法的对象都可称之为迭代器,但对象本身是什么类型不受限制,可以自定义为任何类

# python3
class Foo:
def __iter__(self):
pass
def __next__(self):
pass
from collections import Iterable
from collections import Iterator
print(isinstance(Foo(), Iterable)) # True
print(isinstance(Foo(), Iterator)) # True

我们并不需要继承 Iterator 就可以实现迭代器的功能。当有一函数希望接收的参数是 Iterator 类型时,但是我们传递的是 Foo 的实例对象,其实也没问题,换成是Java等静态语言,就必须传递 Iterator或者是它的子类。鸭子类型通常得益于"不"测试方法和函数中参数的类型,而是依赖文档、清晰的代码和测试来确保正确使用,这既是优点也是缺点,缺点是需要通过文档才能知道参数类型,为了弥补这方面的不足,Python3.6引入了类型信息,定义变量的时候可以指定类型,例如:

def greeting(name: str) -> str:
return 'Hello ' + name

该函数表示接收str类型的参数,并返回str类型的值

(0)

相关推荐

  • 详解duck typing鸭子类型程序设计与Python的实现示例

    在程序设计中,鸭子类型(英语:duck typing)是动态类型的一种风格.在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由当前方法和属性的集合决定. 这个概念的名字来源于由James Whitcomb Riley提出的鸭子测试,"鸭子测试"可以这样表述: "当看到一只鸟走起来像鸭子.游泳起来像鸭子.叫起来也像鸭子,那么这只鸟就可以被称为鸭子." 在鸭子类型中,关注的不是对象的类型本身,而是它是如何使用的.例如,在不使用鸭子类型的语言中

  • 在Python运行时动态查看进程内部信息的方法

    接前两篇"运行时查看线程信息"的博客,我在想,既然我可以随时打印线程信息,那么我是不是可以随时打印进程内部的其它信息呢?比如,实时查看一些对象属性等,这样可以帮助我们在不重新启动应用程序的情况下就可以观察进程的执行状态.(这里暂时不考虑那些使用第三方库或工具的情况) 根据这个想法,查看了一下python的动态加载模块的方法,感觉这个想法还是比较靠谱,应该可以实现,所以动手写了个小测试验证了一把.(这里说明一下,只是验证性的,生产环境要使用的话,还是有不少问题需要考虑的.) 下面就是测试

  • python 动态生成变量名以及动态获取变量的变量名方法

    前言 需求: 必须现在需要动态创建16个list,每个list的名字不一样,但是是有规律可循,比如第一个list的名字叫: arriage_list_0=[],第二个叫arriage_list_1=[]--..依次类推,但是我又不想手动的去写16个这样的名字,太累了,而且增加了代码的冗余性,灵活性也不强,所以有没有一种方法是能动态创建list名称的呢?答案是有的!而与之对应,既然要对上面的列表动态操作,肯定是少不了动态去解析list名称.所以下面开始介绍方法. python 动态生成变量名 lo

  • 【python】matplotlib动态显示详解

    1.matplotlib动态绘图 python在绘图的时候,需要开启 interactive mode.核心代码如下: plt.ion(); #开启interactive mode 成功的关键函数 fig = plt.figure(1); for i in range(100): filepath="E:/Model/weights-improvement-" + str(i + 1) + ".hdf5"; model.load_weights(filepath);

  • 详细介绍Python的鸭子类型

    鸭子类型基本定义 首先Python不支持多态,也不用支持多态,python是一种多态语言,崇尚鸭子类型. 以下是维基百科中对鸭子类型得论述: 在程序设计中,鸭子类型(英语:duck typing)是动态类型的一种风格.在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由当前方法和属性的集合决定.这个概念的名字来源于由James Whitcomb Riley提出的鸭子测试,"鸭子测试"可以这样表述: "当看到一只鸟走起来像鸭子.游泳起来像鸭子.叫起来也

  • Python图像处理之gif动态图的解析与合成操作详解

    本文实例讲述了Python图像处理之gif动态图的解析与合成操作.分享给大家供大家参考,具体如下: gif动态图是在现在已经司空见惯,朋友圈里也经常是一言不合就斗图.这里,就介绍下如何使用python来解析和生成gif图像. 一.gif动态图的合成 如下图,是一个gif动态图. gif动态图的解析可以使用PIL图像模块即可,具体代码如下: #-*- coding: UTF-8 -*- import os from PIL import Image def analyseImage(path):

  • 老生常谈python之鸭子类和多态

    一. 什么是多态 <1>一种类型具有多种类型的能力 <2>允许不同的对象对同一消息做出灵活的反应 <3>以一种通用的方式对待个使用的对象 <4>非动态语言必须通过继承和接口的方式来实现 二. python中的多态 <1>通过继承实现多态(子类可以作为父类来使用) <2>子类通过重载父类的方法实现多态 class Animal: def move(self): print('animal is moving....') class Do

  • Python动态语言与鸭子类型详解

    今天来说说编程语言中的动态类型语言与鸭子类型. 动态语言 维基百科对动态语言的定义: 动态编程语言是一类在运行时可以改变其结构的语言:例如新的函数.对象.甚至代码可以被引进,已有的函数可以被删除或是其他结构上的变化.动态语言目前非常具有活力如PHP.Ruby.Python 都属于动态语言,而C.C++.Java等语言则不属于动态语言. 这个解释很抽象,其实动态语言是相对静态语言而言的,静态语言的特点是在程序执行前,代码编译时从代码中就可以知道一切,比如变量的类型,方法的返回值类型: String

  • C语言中自定义类型详解

    目录 结构大小 offsetof 结构体对齐规则 存在原因 总结 结构大小 我们先随便给出一个结构体,为了计算他的大小,我给出完整的打印方案: typedef struct num { char c; int n; char cc; }num; int main() { printf("%d\n", sizeof(num)); return 0; } 好了,按道理来说我计算一个结构体大小就看他的各个成员需要消耗多大的空间, num 结构体中三个成员分别是 char ,int ,char

  • Python中函数的参数类型详解

    目录 1.Python的函数参数的类型 2.Python的必传参数 3.关键字参数 4.默认参数 5.不定长参数 1.Python的函数参数的类型 必传参数:调用函数时必须传入的参数,函数定义时只定义参数名 关键字参数:传入时以函数的参数名值对的方式传入 默认参数:函数定义时为参数默认设置一个值,调用时不传输参数即以默认值处理 不定长参数:以*修饰或者**修饰的参数;*修饰的参数是一个元组(tuple),**修饰的参数必须是字典(dict),通常写作*args或者**args 2.Python的

  • python 多态 协议 鸭子类型详解

    接口(python 中的协议)的多种不同的实现方式即为多态.多态的作用,就是为了类在继承和派生的时候,保证使用"家谱"中任一类的实例的某一属性时的正确调用. from abc import ABCMeta, abstractmethod # 鸭子类 class Dock(metaclass=ABCMeta): @abstractmethod def Swimming(self): # 游泳方法协议(接口) pass @abstractmethod # 走路协议(接口) def Walk

  • Go语言之嵌入类型详解

    一.什么是嵌入类型 先看如下代码: type user struct { name string email string } type admin struct { user // Embedded Type level string } 可以看到admin结构中的一个成员是user,那么admin中就嵌入了user类型. admin也叫做外部类型 user也叫做内部类型 二.外部类型和内部类型之间的关系和机制 func (u *user) notify() { fmt.Printf("Sen

  • Python中的面向接口编程示例详解

    前言 "面向接口编程"写 Java 的朋友耳朵已经可以听出干茧了吧,当然这个思想在 Java 中非常重要,甚至几乎所有的编程语言都需要,毕竟程序具有良好的扩展性.维护性谁都不能拒绝. 最近无意间看到了我刚开始写 Python 时的部分代码,当时实现的需求有个很明显的特点: 不同对象具有公共的行为能力,但具体每个对象的实现方式又各不相同. 说人话就是商户需要接入平台,接入的步骤相同,但具体实现不同. 作为一个"资深" Javaer,需求还没看完我就洋洋洒洒的把各个实现

  • Python的语言类型(详解)

    Python 是强类型的动态脚本语言 . 强类型:不允许不同类型相加 动态:不使用显示数据类型声明,且确定一个变量的类型是在第一次给它赋值的时候 脚本语言:一般也是解释型语言,运行代码只需要一个解释器,不需要编译 强类型语言和弱类型语言 1.强类型语言:使之强制数据类型定义的语言.没有强制类型转化前,不允许两种不同类型的变量相互操作.强类型定义语言是类型安全的语言,如Java.C# 和 python,比如Java中"int i = 0.0;"是无法通过编译的: 2.弱类型语言:数据类型

  • C语言静态与动态通讯录的实现流程详解

    目录 静态通讯录 contact.h contact.c test.c 动态通讯录 contact.h contact.c qsort.c test.c 本次通讯录的代码已经放到我的Gitee仓库中,感兴趣的小伙伴可以去看看 Gitee 静态通讯录 在我们学习完C语言的结构体.指针以及动态内存管理之后,我们就可以实现一些有意思的小项目了,通过这些小项目可以加深我们对于相关知识的理解. 静态通讯录主要要求有 静态大小,可以记录10个人的信息(大小自己定) 记录的信息如下:名字.性别.年龄.电话.住

  • 对Python中画图时候的线类型详解

    在Python中用matplotlib画图的时候,为了区分曲线的类型,给曲线上面加一些标识或者颜色.以下是颜色和标识的汇总. 颜色(color 简写为 c): 蓝色: 'b' (blue) 绿色: 'g' (green) 红色: 'r' (red) 蓝绿色(墨绿色): 'c' (cyan) 红紫色(洋红): 'm' (magenta) 黄色: 'y' (yellow) 黑色: 'k' (black) 白色: 'w' (white) 灰度表示: e.g. 0.75 ([0,1]内任意浮点数) RG

  • Python 变量类型详解

    变量存储在内存中的值.这就意味着在创建变量时会在内存中开辟一个空间. 基于变量的数据类型,解释器会分配指定内存,并决定什么数据可以被存储在内存中. 因此,变量可以指定不同的数据类型,这些变量可以存储整数,小数或字符. 变量赋值 Python 中的变量赋值不需要类型声明. 每个变量在内存中创建,都包括变量的标识,名称和数据这些信息. 每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建. 等号(=)用来给变量赋值. 等号(=)运算符左边是一个变量名,等号(=)运算符右边是存储在变量中的值. 例

随机推荐