Duck Typing与协议 vs. 继承

如何用Golang来手撸一个Blog - Milu.blog 开发总结 麋鹿博客: 基于Golang, Gin, Gorm, Mysql, Vuejs 的一款轻量级个人博客 阅读详情

在ruby-core邮件列表中,一个关于Ruby中动态类型的问题引发了一系列讨论:

\
根据irb中的运行结果:

\u0026gt;\u0026gt; StringIO.is_a?(IO)


\u0026gt;\u0026gt; =\u0026gt;false

对我来说,这看起来不合逻辑。是有意而为之吗?如果是的话,为什么?

\

有一种答案是这样的:

\
因为StringIO没有使用IO作为它的基类实现,所以它不是IO。

不过这又有什么关系呢?如果你使用标准的Duck Typing,这根本就无所谓。使用Duck Typing时,类的层次关系无关紧要。类只不过是Duck Typing的一种实现细节。你也不用关心#is_a?、#respond_to?等方法。只要假定对象提供你要调用的方法,然后调用它们就可以了。

\

原来的问题(以及邮件列表辩论中出现的一些帖子)应该是来自对OOP中继承所担当的角色的混淆。StringIO和IO不需要同样的超类,因为它们之间没有任何共同之处,除一点之外:它们支持的一系列方法。

\

看来这就是Duck Typing的基本想法:让对象可以响应一系列方法就够了,没必要要求它属于某个类型。

\

此处没有什么新概念,也不是Ruby特有的东西。将“方法”这个词换成OOP的术语“消息”,上面的句子就变为:“【……】让对象可以响应一系列消息”。听起来真的很像是某个(网络)协议(Protocol)的概念。毕竟,如果一个系统可以理解并响应诸如“PUT”、“GET”、“POST”等以特定的方式发送给它的消息,就可以说它理解HTTP协议。

\

让我们进一步看看这个想法:某个客户端,比如说Web浏览器,只关心它通信的服务器是否理解HTTP,它才不管服务器是什么类型呢。总之:如果Mosaic浏览器被硬编码为需要另一端的服务器是NCSA或Netscape的HTTP服务器,互联网恐怕就不会像现在这样蓬勃发展了。通过忽略通信另一端的类型,并且只要求以特定的方式回应“GET”消息,Web开发的两端(服务器端与客户端)都可以彼此独立地进行演化。

\

这种方式与协议的类似之处,OOP编程语言的使用者们在很久以前就已经很明白了。Smalltalk与ObjectiveC,作为动态OOP语言,早就使用“协议”(Protocol)这个词来指代此概念了。

\

协议的概念当然很有用,正好用来给特定的信息定一个名称。这也有助于澄清上述邮件列表中争论的问题。StringIO与IO共享的不是共同的祖先,而是共同的协议。

\

此概念并不仅限于动态语言。在一些静态语言中,比如Java就通过引入接口,而向前跨进了一大步。接口被用来:

\
  • 命名一系列信息 \
  • 静态检查一个类是否实现了这些信息
    \

虽然在一些语言中,比如C++,通过抽象基类和多继承也能做得到,但抽象基类混淆了继承和协议的概念。

\

当然,静态检查的保障是有限的 :接口只能检查一些有特定签名的方法——它不能保证方法的行为,甚或是方法的返回值,甚至也不能保证方法是可以被调用的——比如说在使用Java的Collection API的时候,要小心应对Java的java.lang.UnsupportedOperationException。

\

毫无疑问,接口也有它们自己的问题,比如演化性。改变一个接口,会破坏所有实现了该接口的类。像Eclipse这样的大型项目,会提供API演化的指导建议,其中规定了一个接口在发布之后就不可以再发生变化。这样的状况下,有时会建议大家多使用抽象类而不是接口,因为抽象类可以添加新的函数,但令其实现为空,这样子类就可以,但是不必实现这些新函数。当然,这个问题可以通过定义粒度合适的接口来解决,每个接口对应一个方法,并且通过对已有接口的扩展来搭建完整的接口集合,每个接口对应一定单独的API调用。

\

要解决保证一个对象支持某个协议这个问题,在Ruby中,可以通过将接口检查委托给一个谓语函数(predicate function)来完成。如下示例:

\
\def supports_api?(obj)\ obj.respond_to?(:length) \u0026amp;\u0026amp; obj.respond_to?(:at)\end \\
\

此做法可行,但是同时会带来一个小问题:respond_to?只对定义在一个类中的方法起作用。如果一个对象用method_missing来实现它的部分接口(例如一个代理),虽然对这些方法的调用没有问题,但针对它们调用respond_to?会返回false。这就是说respond_to?检查可以工作,但是它不适合用来替换静态检查(Rick de Natale将这种编码风格称为“Chicken Typing”,这是防御性编程的一种)。

\

另一种静态定义细粒度接口的方式是Scala语言的结构化类型:

\
def setElementText(element : {def setText(text : String)}, text : String) = 
{
element.setText(text.trim()
.replaceAll(\"\\
Python typing实战:从函数签名到CI门禁的类型契约工程 Python作为动态语言,天然缺乏编译期类型约束,导致运行时隐性错误频发,如None穿透、字符串误参与数值计算等。typing module通过静态类型提示机制,在不改变运行行为的前提下,构建可验证的接口契约。其核心价值在于提升协作确定性与故障拦截前置性——借助mypy等检查器,在编码阶段即发现类型不匹配,而非等待线上报错。典型应用场景包括API参数校验、数据管道字段保障、跨模块调用契约定义等。本文聚焦真实项目落地路径,详解函数签名优先策略、TypedDict结构化字典、Protocol鸭子类型协议及渐进式 阅读详情

相关推荐

Python的鸭子类型(Duck Typing)含义是什么?

在静态类型语言中,对象的类型决定了其能力;而在Python的世界里,对象的能力决定了其类型——这就是​​的核心哲学。其名称源自一句谚语:“​​”。在编程语境下,它意味着​​。

efjgt64843的博客 958

Cordova、Meteor禁用iOS 摇晃出现Undo Typing

最近有一个项目的iOS 端摇晃会出现Undo Typing 的问题,下面记录一下解决的方法 问题的现象: 解决方法: 1.可通过npm或者Cordova 添加这个包 cordova plugin add cordova-plugin-ios-disableshaketoedit 包的原网址: https://www.npmjs.com/package/cordova-plugin-ios-...

陈啟华的博客 6538

手把手教你用CMake和MinGW64编译libuvc:静态链接与动态链接的选择

本文详细指导如何在Windows平台上使用CMake和MinGW64编译libuvc库,并深入探讨静态链接与动态链接的选择策略。通过对比两种链接方式在部署复杂度、内存占用和版本管理等方面的差异,帮助开发者根据项目需求做出最优决策,实现高效的USB摄像头开发。

weixin_29171087的博客 255

Java 10 var关键字详解和示例教程

\u0026#xD;关键要点\u0026#xD;\u0026#xD;Java 10引入了一个闪亮的新功能:局部变量类型推断。对于局部变量,现在可以使用特殊的保留类型名称“var”代替实际类型。\u0026#xD;\t提供这个特性是为了增强Java语言,并将类型推断扩展到局部变量的声明上。这样可以减少板代码,同时仍然保留Java的编译时类型检查。\u0026#xD;\t由于编译器需要通过检查赋值等式...

cpongo011702 1007

实用电路精讲系列---快速精密桥式放大器电路

快速精密桥式放大器通过惠斯通电桥转换物理量为差分信号,经仪表放大器精密放大,具有高共模抑制、低噪声和宽带宽特性。其核心包含:电桥传感器转换、仪表放大器信号调理(增益可调、温漂补偿)、输出级适配ADC。典型应用包括智能断路器监测、胎压检测、电池安全预警等10大领域,需注意传感器-放大器-ADC最短路径布局。实用电路采用LT1057S和LT1010构建,实现稳定供电、差分处理、功率放大和桥式驱动,满足高精度、快速响应需求。该技术在工业控制、医疗设备等领域具有重要价值。

weixin_40590799的博客 1415

SolidWorks有限元分析流程

对于很多专业,在进行设计完成后,为了缩短开发周期,往往需要配合仿真结果进行,机械行业更是如此。平时大家多采用专业有限元仿真软件进行仿真分析,如ANSYS;不过SolidWorks软件因为制图简单,同时存在专用的有限元仿真模块Simulation,对于初学者往往更加适用,下面简单介绍下SolidWorks Simulation仿真流程。 1. 分析流程 关键步骤如下: **(1)创建算例;**对模型的每次分析都是一个算例,一个模型可以包含多个算例。 **(2)应用材料;**指定模型的材料属性,如铝合金、钢材等

DYH_BK的博客 3万+

python类型检测最终指南--Typing的使用

点击上方蓝字关注正文共:30429 字预计阅读时间:76分钟原文链接:https://realpython.com/python-type-checking/作者:Gei...

湾区人工智能 3203

C#与倍福TwinCAT3通信实战:ADS协议封装与设备变量读写完整源码

倍福(Beckhoff)TwinCAT3 作为工业自动化领域主流的软PLC系统,其内置的ADS(Automation Device Specification)协议是实现上位机与TwinCAT3通信的核心标准。传统ADS通信开发存在门槛高(协议细节复杂)、稳定性差(缺乏统一异常处理)、复用性低(重复编码)等问题。本文基于 C# 技术栈,聚焦“协议封装标准化、变量读写易用化、通信稳定工业化”核心需求,提供一套完整的 ADS 协议封装方案与设备变量读写源码。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 1987

模板引擎 pongo2

为什么80%的码农都做不了架构师?>>> ...

weixin_34116110的博客 720

从零实现深度学习框架【实现自己的PyTorch(已完结)】

本着“凡我不能创造的,我就不能理解”的思想,此系列文章会基于纯Python以及NumPy从零创建自己的深度学习框架,该框架类似PyTorch能实现自动求导。

日积月累,天道酬勤 6862

Android AVB 分析(十三)dm-verity 设备是如何映射的?

在上一篇《Android AVB 分析(十二)嵌入式设备安全中的 dm-verity 简介》介绍 dm-verity 原理的时候,作者提供了一个 dm-verity 演示的例子。本篇我们基于 AOSP 源码 `android-13.0.0_r41` 实际编译生成的 Google Pixel 7 (“panther”) 设备的 system 分区镜像进行 dm-verity 设备验证实战。

洛奇看世界 2438

C++的模板duck typing和继承的区别

但这两种还是差别较大,duck typing例子里面的函数somefunc,不光可以接受duck,任何具有sing接口的对象,都可以调用。但在调用时必须知道具体类型。在模板的世界里,具体类型是很重要的。在模板的方式里,接口更像是duck们所具有的某种属性,你只要有,那么就可以。简而言之,如果你在调用的时候就知道具体类型,那么可以用模板。如果你不知道具体类型,那么就可以用继承。

tumu_C的博客 292

SAP 系统升级不再惧怕 SPAU 与 SPDD:把修改调整做成可控的工程

SAP系统升级中的SPAU/SPDD处理要点:首先明确SPDD处理数据字典对象,SPAU处理程序对象,核心是解决标准对象变更与历史修改的继承问题。关键原则是优先回归标准版本,减少后续升级负担。操作时应利用版本管理对比差异,批量处理可回退对象,并通过F9多选提高效率。对于提示"当前版本与建议一致"的对象直接回归标准。注意区分新旧SPAU界面功能差异,将Note下载移至SNOTE处理,并确保在SPDD/SPAU之后处理SPAU_ENH。最后,所有调整需记录日志并纳入传输请求,确保可追溯性。遵

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 390

Interview_Question_for_Beginner 实战指南:Python 核心机制与面试要点全解析(生成器、MRO、GIL、GC、Duck Typing 与 Timsort)

本文是技术面试指南项目 Part 2(语言篇)中 [Python](https://link.gitcode.com/i/1135bf06f20504d4172fa568c01e1402) 主题的完整展开。它以预备开发者(beginner)为目标读者,系统梳理了 Python 面试中最常被追问的 9 个核心主题:生成器(Generator)、类继承时的方法解析(MRO)、GIL 与性能问题、垃圾回

gitblog_00663的博客 415

基于YOLOv5的仪表读数识别系统:从检测到识别的完整解决方案

随着工业自动化水平的不断提高,仪表读数识别技术在电力系统、石油化工、智能制造等领域发挥着越来越重要的作用。本文提出了一种基于YOLOv5的仪表自动读数识别系统,该系统能够有效区分指针式和数字式仪表,并实现高精度的读数识别。我们详细介绍了系统的整体架构、数据集构建、模型训练策略以及用户界面设计,并提供了完整的代码实现。实验结果表明,本系统在仪表检测和读数识别任务上均取得了优异的表现,为工业现场的自动化监控提供了可靠的技术支持。关键词:仪表读数识别;YOLOv5;目标检测;深度学习;工业自动化。

YOLO 679

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Python 里的“鸭子类型”(Duck Typing)

摘要: 鸭子类型强调通过对象的行为(方法/属性)而非类型来判断其可用性,使代码更灵活。例如,只要对象有.write()方法,就可视为可写对象。常配合EAFP(先尝试后处理异常)使用,避免类型检查与调用间的竞态问题。Python的typing.Protocol可静态检查行为匹配,兼顾灵活性与安全性。典型应用包括文件类对象、可迭代对象等。优点是低耦合、易测试,但需注意运行时错误风险,可通过文档、Protocol和EAFP缓解。核心思想是“按能力编程”,提升代码复用性和扩展性。

keyboard专栏 252

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

Python抽象基类vs协议对比

print(isinstance("hello", Hashable)) # True——str 有 __hash__"""实现 Sequence 接口——自动获得 __contains__、__iter__ 等"""ABC 侧重"是什么"(显式接口),Protocol 侧重"能做什么"(结构子类型)。"""可哈希接口——使用 __subclasshook__ 自动检测""""""飞机——也有 fly 方法,同样满足 Flyable 协议"""

raoxiaoz0425的博客 117

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

深入理解go语言-第6章 接口与面向组合设计

文章摘要 Go语言通过独特的接口设计实现了"组合优于继承"的编程哲学。其接口系统主要特点包括: 隐式实现:类型无需显式声明实现接口,只要包含接口所有方法即自动满足,实现接口与实现的解耦 Duck Typing:"像鸭子一样走路和叫的就是鸭子"的设计理念,强调行为而非类型 接口值双层结构:包含动态类型和动态值,需注意nil指针赋给接口后的非nil判断 空接口与类型断言:interface{}或any可接收任意类型,配合类型断言实现运行时类型检查 接口组合:遵循小接口原则,通过组合多个小接口构建复杂功能 这种设

andrewbytecoder 328

Dynamic 动态类型 和双问号??的使用

1.dynamic关键字用于声明一个动态对象,然后通过该动态对象去调用方法或读写属性。以前我们都是在运行时通过反射,Emit,CodeDom等技术来完成。创建一个dynamic类型的对象需要使用一个特殊的构建器叫ExpandoObject。 dynamic aehyok = new ExpandoObject(); aehyok.Name =

guoduhua的专栏 605

.Net 4.0 之 Dynamic 动态类型

一、.net4.0主要新特性         .Net4.0在.Net3.5基础上新增的主要特性有:可选参数、命名参数和Dynamic。具体请阅生鱼片的这篇博文。这里我们着重讲解C#4.0的Dynamic特性,对于其他特性大家可以在VS2010内尝试一下。总之.Net在不断进步中。        二、ExpandoObject普通应用          Expand

黄毛的专栏 429

【python高级编程教程】笔记(python教程、python进阶)第三节:(1)多态与鸭子类型(Polymorphism and Duck Typing)

鸭子类型”(Duck typing)是一种编程概念,它更注重对象的行为,而不是对象所属的类型。这个词源自James Whitcomb Riley的名言:“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。在Python中,"鸭子类型"指的是对对象的处理方式:如果一个对象实现了某个方法或者特性,那么就可以认为它就是那个类型。也就是说,一个对象的类型并不取决于它继承自什么类,或者实现了什么接口,而是取决于它有什么行为(或者说,具备哪些能力)。

Dontla的博客 1188

7-Zip-zstd:让 7-Zip 原生支持 6 种现代压缩算法

7-Zip-zstd 是 7-Zip 的扩展版,支持 Zstandard、Brotli 等 6 种无损压缩算法。与标准 7-Zip 的差异:能直接创建和打开 .zst、.br、.lz4 文件,加密与哈希能力也一并扩展。 ## 核心能力一览:6 种压缩算法加认证加密 | 功能模块 | 具体支持项 | 适用场景 | | --- | --- | --- | | Zstandard | 级别 1–22

gitblog_00583的博客 467

Python 继承(Inheritance)完全指南:从 OOP 基础语法到低层设计实战

本文以 [oop/python/inheritance/README.md](https://link.gitcode.com/i/339dbf9e128f3eebc20476ea700899b4) 为骨架,系统讲解 Python 面向对象编程中的**继承(Inheritance)**机制:从父类/子类的基础语法、四种继承类型、方法重写与 `super()` 用法,到该机制在低层设计(LLD)项目

gitblog_00153的博客 785

Python设计模式退化:从GOF到协议思维的工程演进

设计模式本质是语言表达力不足时的结构补偿机制。在Java、C#等静态类型语言中,Strategy、Observer、Factory等模式通过类继承与接口约束显式建模行为契约;而Python凭借函数即对象、鸭子类型、装饰器和Protocol协议等原生特性,将大量模式逻辑下沉为运行时语义或数据结构,实现‘隐式契约’替代‘显式接口’。这种范式迁移提升了代码可读性、可测试性与迭代效率,尤其适用于微服务快速验证、跨语言重构及动态系统集成场景。本文聚焦Python中设计模式的自然退化现象,结合真实生产案例解析协议驱动、

didi9310的博客 374
上一篇: InfoQ中文站第48周精彩新闻回顾
下一篇: 访问不了blogspot的解决方法
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值