网站首页 > 技术文章 正文

我们都知道,在java中有接口(interface)的概念,类可以实现多个接口,但是必须要实现所有接口中的方法,但是在python 中并没有接口的概念,类可以通过多继承的方式继承自多个类,现在如果我们想要实现在java中的接口的效果,强制要求子类必须实现一些方法,该如何操作呢?
抽象类的实现
python 在有个ABCMeta类,如果定义类的时候,设置元类(metaclass) 为 ABCMeta 时,并且定义了抽象方法,则该类不可以直接初始化。
import abc
class Runable(metaclass=abc.ABCMeta):
@abc.abstractmethod
def run(self):
pass
r = Runable()
上面我们定义了一个Runable 类,并设置元类为abc.ABCMeta,我们在该类中定义了一个run方法,并且使用@abc.abstractmethod 进行装饰,这种情况下,当尝试使用 r = Runable() 来初始化一个实例时,则会抛出一个异常 TypeError: Can't instantiate abstract class Runable with abstract method run
但是如果将@abc.abstractmethod 装饰器去掉,则可以正常的实例化
我们也可以继承自abc.ABC类来定义类,效果和上面是一样的,abc.ABC 类是一个包装类
class ABC(metaclass=ABCMeta):
"""Helper class that provides a standard way to create an ABC using
inheritance.
"""
__slots__ = ()
class Runable(abc.ABC):
def run(self):
print("can run .....")
如果在定义类的时候,既没有继承abc.ABC,也没有设置metaclass=ABCMeta,则即使在方法上加上abstractmethod装饰器,也不会起到抽象类的作用,还是可以正常的初始化实例。 但是如果没有定义抽象方法,也是可以正常的实例的
所以我们得出以下结论,想要实现抽象类的效果,即要满足两个条件
- 类继承自abc.ABC或者 设置元类为abc.ABCMeta
- 在类中定义抽象方法,即使用abc.abstractmethod装饰的方法
实现抽象类的子类
抽象类的初衷是定义规则,要求子类必须要实现哪些方法,当某个子类继承自某个抽象类,并且全部实现了抽象类中的方法,则该类可以正常的实例化,否则也不可以实例化
class Runable(metaclass=abc.ABCMeta):
@abc.abstractmethod
def run(self):
pass
@abc.abstractmethod
def walk(self):
pass
class Dog(Runable):
def run(self):
print("dog run ")
上面的Dog 类只是实现了Runable 的run方法,并没有实现walk 方法,则还是不能正常地实例化。
这里有一个注意点,子类对于父类中的抽象方法,并不一定要求和抽象方法的函数签名一致,这点真的是很诧异, 看以下代码
class Runable(metaclass=abc.ABCMeta):
@abc.abstractmethod
def run(self):
pass
@abc.abstractmethod
def walk(self, name):
pass
class Dog(Runable):
def run(self):
print("dog run ")
def walk(self):
print("dog walk")
d = Dog()
d.run()
d.walk()
抽象类Runable 中定义walk 方法的签名为 def walk(self, name): 这里需要有一个name参数, 但是子类在实现的时候,并没有该参数,在python 中,认为这种也算实现了walk 抽象方法,但是IDE会给出一个警告
Signature of method 'Dog.walk()' does not match signature of base method in class 'Runable'
上面的代码可以正常的运行,也就是说,Dog 类可以正常地初始化,这个就不得吐槽一下了!
- 上一篇: 让我们详细学习下Python类吧!
- 下一篇: 二、python类定义的讲解
猜你喜欢
- 2025-01-08 Python | 搞懂类的继承
- 2025-01-08 Python 类常用各种方法及区别
- 2025-01-08 python标识符
- 2025-01-08 站长在线Python教程:python中面向对象相关概述详解
- 2025-01-08 Python类的定义、封装、继承和多态
- 2025-01-08 深入探讨Python类函数的一些高级用法(封装)
- 2025-01-08 Python 知识点 #22 - 元类
- 2025-01-08 二、python类定义的讲解
- 2025-01-08 让我们详细学习下Python类吧!
- 2025-01-08 Python 30 天进阶:类的继承与多态之妙
- 272℃Python短文,Python中的嵌套条件语句(六)
- 271℃python笔记:for循环嵌套。end=""的作用,图形打印
- 269℃PythonNet:实现Python与.Net代码相互调用!
- 264℃Python实现字符串小写转大写并写入文件
- 263℃Python操作Sqlserver数据库(多库同时异步执行:增删改查)
- 122℃原来2025是完美的平方年,一起探索六种平方的算吧
- 104℃Python 和 JavaScript 终于联姻了!PythonMonkey 要火?
- 98℃Ollama v0.4.5-v0.4.7 更新集合:Ollama Python 库改进、新模型支持
- 最近发表
-
- Python数据分析实战-dataframe分组提取每一组的首条记录
- 如何使用Python将多个excel文件数据快速汇总?
- 「Python数据分析」Pandas进阶,使用groupby分组聚合数据(二)
- 还在熬夜合并30个Excel 3个案例,带你用Python玩转Excel高阶操作
- python数据分析实战:pandas分组聚合-自定义聚合函数
- Python 知识点 #31 - 分组和聚(python分层聚类)
- 人生苦短,自学 python——pandas 的分组操作
- 利用Python进行数据分组/数据透视表
- 超实用!用Python快速实现数据分组统计与透视表
- Python 之 Pandas:数据分组聚合统计的魔法秘籍
- 标签列表
-
- python中类 (31)
- python 迭代 (34)
- python 小写 (35)
- python怎么输出 (33)
- python 日志 (35)
- python语音 (31)
- python 工程师 (34)
- python3 安装 (31)
- python音乐 (31)
- 安卓 python (32)
- python 小游戏 (32)
- python 安卓 (31)
- python聚类 (34)
- python向量 (31)
- python大全 (31)
- python次方 (33)
- python桌面 (32)
- python总结 (34)
- python浏览器 (32)
- python 请求 (32)
- python 前端 (32)
- python验证码 (33)
- python 题目 (32)
- python 文件写 (33)
- python中的用法 (32)