python如何实现面向接口编程?(python如何面向对象编程)
off999 2024-10-17 11:45 52 浏览 0 评论
前言
”面向接口编程“写 Java 的朋友耳朵已经可以听出干茧了吧,当然这个思想在 Java 中非常重要,甚至几乎所有的编程语言都需要,毕竟程序具有良好的扩展性、维护性谁都不能拒绝。
最近无意间看到了我刚开始写 Python 时的部分代码,当时实现的需求有个很明显的特点:
- 不同对象具有公共的行为能力,但具体每个对象的实现方式又各不相同。
说人话就是商户需要接入平台,接入的步骤相同,但具体实现不同。
作为一个”资深“ Javaer,需求还没看完我就洋洋洒洒地把各个实现类写好了:
当然最终也顺利实现需求,甚至把组里一个没写过 Java 的大哥唬的一愣一愣的,直呼牛逼。
不过事后也给我吐槽:
- 你这设计是不错,但是感觉好复杂,跟代码时要找到真正的业务逻辑(实现类)得绕几圈。
截止目前 Python 写多了,我总算是能总结他的感受:就是不够 Pythonic。
虽说 Python 没有类似 Java 这样的 Interface 特性,但作为面向对象的高级语言也是支持继承的;
在这里我们也可以利用继承的特性来实现面向接口编程:
class Car:
def run(self):
pass
class Benz(Car):
def run(self):
print("benz run")
class BMW(Car):
def run(self):
print("bwm run")
def run(car):
car.run()
if __name__ == "__main__":
benz = Benz()
bmw = BMW()
run(benz)
run(bmw)
代码非常简单,在 Python 中也没有类似于 Java 中的 extends 关键字,只需要在类声明末尾用括号包含基类即可。
这样在每个子类中就能单独实现业务逻辑,方便扩展和维护。
类型检查
由于 Python 作为一个动态类型语言,无法做到 Java 那样在编译期间校验一个类是否完全实现了某个接口的所有方法。
为此 Python 提供了解决办法,那就是 abc(Abstract Base Classes) ,当我们将基类用 abc 声明时就能近似做到:
import abc
class Car(abc.ABC):
@abc.abstractmethod
def run(self):
pass
class Benz(Car):
def run(self):
print("benz run")
class BMW(Car):
pass
def run(car):
car.run()
if __name__ == "__main__":
benz = Benz()
bmw = BMW()
run(benz)
run(bmw)
一旦有类没有实现方法时,运行期间便会抛出异常:
bmw = BMW()
TypeError: Can't instantiate abstract class BMW with abstract methods run
虽然无法做到在运行之前(毕竟不需要编译)进行校验,但有总比没有好。
鸭子类型
以上两种方式看似已经毕竟优雅的实现面向接口编程了,但实际上也不够 Pythonic。
在继续之前我们先聊聊接口的本质到底是什么?
在 Java 这类静态语言中面向接口编程是比较麻烦的,也就是我们常说的子类向父类转型,因此需要编写额外的代码。
带来的好处也是显而易见,只需要父类便可运行。
但我们也不必过于执着于接口,它本身只是一个协议、规范,并不特指 Java 中的 Interface,甚至有些语言压根没有这个关键字。
动态语言的特性也不需要强制校验是否实现了方法。
在 Python 中我们可以利用鸭子类型来优雅的实现面向接口编程。
在这之前先了解下鸭子类型,借用维基百科的说法:
- “当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”
我用大白话翻译下就是:
即便两个完全不相干的类,如果他们都实现了相同的方法,那就可以把他们当做同一类型的类来使用。
举个简单例子:
class Order:
def create(self):
pass
class User:
def create(self):
pass
def create(obj):
obj.create()
if __name__ == "__main__":
order = Order()
user = User()
create(order)
create(user)
这里的 order 和 user 本身完全没有关系,只是他们都有相同方法,又得益于动态语言没法校验类型的特点,所以完全可以在运行的时候认为他们是同一种类型。
因此基于鸭子类型,之前的代码我们可以稍作简化:
class Car:
def run(self):
pass
class Benz:
def run(self):
print("benz run")
class BMW:
def run(self):
print("bwm run")
def run(car):
car.run()
if __name__ == "__main__":
benz = Benz()
bmw = BMW()
run(benz)
run(bmw)
因为在鸭子类型中我们在意的是它的行为,而不是他们的类型;所以完全可以不用继承便可以实现面向接口编程。
总结
我觉得平时没有接触过动态类型语言的朋友,在了解完这些之后会发现新大陆,就像是 Python 老手第一次使用 Java 时;虽然觉得语法啰嗦,但也会羡慕它的类型检查、参数验证这类特点。
动静语言之争这里不做讨论了,各有各的好,鞋好不好穿只有自己知道。
随便提一下其实不止动态语言具备鸭子类型,有些静态语言也能玩这个骚操作,感兴趣下次再介绍。
相关推荐
- 安卓模拟器电脑版(安卓模拟器电脑版下载)
-
BlueStacks安卓模拟器 是一款十分好用的安卓模拟器。该软件非常的不错,采用了LayerCake技术可使用一些ARM特殊指令集,而且使用它能够让大部分的安卓应...
-
- 靠比较好的软件下载网站(靠比较好的软件下载网站动漫)
-
官网下载最好通过官网下载,最大的好处是能够保证软件的原汁原味,不怕病毒。其安装程序不会被恶意篡改,保证了应用过程中的安全性。但是缺点也是存在的。一些软件通过官网下载的时候速度非常慢,尤其对于Office、VisualStudio等国外的主...
-
2026-01-08 06:51 off999
- 大白菜一键重装系统步骤(大白菜重装系统详细步骤)
-
1.登录大白菜官网【www.winbaicai.com】,下载最新版的大白菜U盘启动盘制作...2.解压并打开大白菜U盘启动盘制作工具,点击切换至【一键还原】界面3.进入一键还原界面之后,选择【我要重...
- 怎么提升电脑配置(如何升级电脑配置提高电脑运行速度)
-
升级电脑配置可以通过以下几个方面来实现。首先,可以更换更快的处理器和更大的内存条,这将提升计算速度和多任务处理能力。其次,更换较新的显卡可以提升图形处理性能,使游戏和图形应用更流畅。此外,更换更大容量...
- 重启就好了(重启就好了吗)
-
一、路由器工作时间过长,热量散发不出去引起的断网很多用户在使用路由器的时候并没有过多的去在意过它的“感受”,会让它处在24小时的工作状态下,其实在路由器长时间工作的情况下,其内部会产生大量的热量,又因...
- 电脑麦克风没声音是什么原因
-
电脑麦克风没有声音可能有多种原因,以下是一些常见的排查步骤:1.检查麦克风连接:确保麦克风正确连接到电脑的麦克风插孔上。如果是通过USB连接的麦克风,也要确保USB连接正常。2.调整麦克风音量:在...
-
- 安全浏览器免费下载(安全刘览器下载)
-
1、打开运行qq浏览器。 2、点击右上方菜单按钮,在弹出的菜单中点击“qq浏览器设置”。? 3、进入“安全与隐私”类目,然后勾选“开启安全网址认证”确定即可。?1.首先打开浏览器,点击左上角的三个点。2.然后在弹出的页面点击“设置”选项...
-
2026-01-08 04:03 off999
- bios无法设置u盘启动(bios无法设置legacy)
-
需要准备的工具:电脑,Bios设置界面。1、以戴尔电脑为例,直接按启动快捷键F12进入启动菜单选择u盘即可,进入BIOS设置。2、进入BIOS设置之后。找到”USBStorageLegacySuppo...
- 电脑重装win7系统后怎么设置
-
1.首先在win7桌面空白处,点击右键弹出菜单,选择个性化。2.调出个性化设置窗口后,我们切换至开始选项卡,然后点击右侧下方的“选择哪些文件夹显示在开始屏幕上”。3.此时一般正常情况下,可以看到设置选...
- 简单常用的dos命令(常见dos命令总结)
-
一些常用的DOS命令包括:1.dir:列出当前目录中的文件和子目录。2.cd:更改当前目录。3.md:创建一个新的目录。4.rd:删除一个目录。5.copy:将文件从一个位置复制到另一个位置...
- 421事件全文免费阅读(421事件文档全文免费阅读)
-
对于421事件的真实性,目前没有确凿的官方消息。关于421事件的真实性,有以下几种观点:1.有人认为421事件总体上是真实的,认为其中的污秽和混乱超过了大多数人的认知,涉及到的封建迷信内容对于一些人...
- 英伟达所有显卡型号(英伟达显卡型号含义)
-
amdcpu搭配英伟达的显卡,显卡性能不会受到影响的。性能不会受到影响,AMD说配三A平台稳定性最强,而且恢复自动超频一点点,制其实那只是AMD的广告而已,没那回事,AMDCPU配英伟达的显卡也没...
- windows无法连接到这个网络(windows无法连接到这个网络 笔记本)
-
有可能是因为无线网络的密码变了,也有可能是系统自身的问题,解决方法:1、右键计算机图标。2、点开服务和应用程序,然后点击下面的服务。3、打开服务后找到WLANAutoConfig无线网络服务。4、W...
- 电脑装机平台(电脑装机城)
-
网上装机京东比较靠谱。要想在网上组装一台靠谱的电脑,真的需要一双慧眼。笔者认为相对靠谱的还是某东自营店,某宝甚至某猫都是满地坑。如果某东也看不上的话,其实到线下实体店购买也是不错的选择,现在线上线下价...
欢迎 你 发表评论:
- 一周热门
-
-
抖音上好看的小姐姐,Python给你都下载了
-
全网最简单易懂!495页Python漫画教程,高清PDF版免费下载
-
Python 3.14 的 UUIDv6/v7/v8 上新,别再用 uuid4 () 啦!
-
飞牛NAS部署TVGate Docker项目,实现内网一键转发、代理、jx
-
python入门到脱坑 输入与输出—str()函数
-
宝塔面板如何添加免费waf防火墙?(宝塔面板开启https)
-
Python三目运算基础与进阶_python三目运算符判断三个变量
-
(新版)Python 分布式爬虫与 JS 逆向进阶实战吾爱分享
-
失业程序员复习python笔记——条件与循环
-
系统u盘安装(win11系统u盘安装)
-
- 最近发表
- 标签列表
-
- python计时 (73)
- python安装路径 (56)
- python类型转换 (93)
- python进度条 (67)
- python吧 (67)
- python的for循环 (65)
- python格式化字符串 (61)
- python静态方法 (57)
- python列表切片 (59)
- python面向对象编程 (60)
- python 代码加密 (65)
- python串口编程 (77)
- python封装 (57)
- python写入txt (66)
- python读取文件夹下所有文件 (59)
- python操作mysql数据库 (66)
- python获取列表的长度 (64)
- python接口 (63)
- python调用函数 (57)
- python多态 (60)
- python匿名函数 (59)
- python打印九九乘法表 (65)
- python赋值 (62)
- python异常 (69)
- python元祖 (57)
