python - “Code against an interface, not an object” 的 Python 版本是什么?

标签 python oop interface inversion-of-control

灵感来自 here. 的一个好问题(和一堆好答案)

“针对接口(interface)而不是对象的代码”语句在 Python 中是否有意义?

我正在寻找类似 Original Question 中的答案,但包含 Python 片段和想法。

最佳答案

“针对接口(interface)而不是对象的代码”在 Python 中没有字面意义,因为该语言没有接口(interface)功能。 rough Python 等价物是“使用鸭子类型”。如果您想查看一个对象是否是鸭子,换句话说,您应该检查它是否有 quack()方法,或者更好的是尝试quack()并提供适当的错误处理,而不是测试它是否是 Duck 的实例.

Python 中常见的鸭子类型是文件(实际上是类文件对象)、映射(dict 类对象)、可调用对象(类函数对象)、序列(list 类对象)和iterables(可以迭代的东西,可以是容器或生成器)。

例如,需要文件的 Python 功能通常会很乐意接受实现 file 方法的对象。它需要;它不需要从 file 派生类(class)。例如,要将对象用作标准输出,它需要的主要内容是 write()方法(也许 flush()close() ,实际上不需要做任何事情)。类似地,可调用对象是任何具有 __call__() 的对象。方法;它不需要从函数类型派生(实际上,你不能从函数类型派生)。

您应该采取类似的方法。检查您要对对象执行的操作所需的方法和属性。更好的是,记录您的期望并假设调用您的代码的人并非完全愚蠢。 (如果他们给你一个你不能使用的对象,他们肯定会从他们得到的错误中足够快地弄清楚这一点。)仅在必要时测试特定类型。 有时是必要的,这就是 Python 为您提供 type() 的原因, isinstance() , 和 issubclass() ,但要小心他们。

Python 的鸭子类型相当于“针对接口(interface)而不是对象的代码”,因为建议您不要让代码过于依赖对象的类型,而是查看它是否具有您需要的接口(interface).不同之处在于,在 Python 中,“接口(interface)”只是指提供某种行为的对象的属性和方法的非正式捆绑,而不是专门命名为 interface 的语言结构。 .

您可以在某种程度上使用 abc 形式化 Python“接口(interface)”。模块,它允许您使用您想要的任何标准声明给定类是给定“抽象基类”(接口(interface))的子类,例如“它具有属性 colortail_lengthquack ,并且 quack 是可调用的。”但这仍然比具有接口(interface)功能的静态语言严格得多。

关于python - “Code against an interface, not an object” 的 Python 版本是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4549018/

相关文章:

python - PyPDF2 'PageObject' 未定义

javascript - Nodejs 为什么用原型(prototype)静态初始化数组?

python - 为什么 super().__init__ 没有自引用?

java - 如何替换长链的if

C#接口(interface)实现关系只是 "Can-Do"关系?

delphi - 如何正确使用ARC与接口(interface)?

c# - 解决缺少枚举继承的问题

python - cx_freeze 和导入模块

python - 当每个脚本在 python 中都有多个线程时,从主脚本同时运行两个脚本

Python正则表达式替换