python-3.x - 如何使用父类强制子类为属性设置值?
问题描述
我希望这个Parent
类有一个检查机制来确保它的所有子类都为属性设置一个实际值name
。我在这里找到了一些东西。
class Parent(object):
#name = None
def __init__(self):
if self.name == None:
raise NotImplementedError('Subclasses must define name')
class Child1(Parent):
pass
class Child2(Parent):
name = 'test'
class Child3(Parent):
def __init__(self):
self.name = 'test'
class Child4(Parent):
def __init__(self):
pass
#obj1 = Child1() # Expected output: NotImplementedError: Subclasses must define bar
obj2 = Child2()
obj3 = Child3()
obj4 = Child4() # I want the NotImplementedError is raised here as well, but it doesn't
问题是只要__init__
子类中有一个方法,它就会覆盖Parent
该类并且raise NotImplementedError
不再有效。
我目前的工作解决方案是:
class Child5(Parent):
def __init__(self):
self.name = 'test'
super().__init__()
obj5 = Child5()
这似乎可行,但我想知道它是否是一个正确的实现,或者它是否可能有一些隐藏的陷阱,以及我是否应该学习使用/实现@abstractproperty
而不是这个解决方案?
解决方案
在这里,您需要了解何时调用父类构造函数。请注意,在创建子类对象时,如果子类有构造函数,则默认调用它。我们是否也想调用父类构造函数取决于我们,这将由我们完成。但是,如果子类没有构造函数,则调用基类构造函数。
因此,对于您的 Child1(),默认情况下会调用父构造函数,因此会引发异常。
在您的 Child2() 中,也调用了父构造函数。但是请注意,name 变量是静态的,甚至可以作为 Child2.name 访问。因此没有例外。
您的 Child3 类有一个构造函数有一个构造函数,因此永远不会调用父构造函数,因此实际上永远不会检查名称是否存在。因此,您确实需要将以下行添加到子构造函数。
super().__init__()
如果构造函数定义了名称,则应在声明名称后进行此调用。这就是你在 Child5 课堂上所做的。
由于与上述完全相同的原因,Child4 中没有捕获到异常。以下将在 Child4 中检查此情况:
class Child4(Parent):
def __init__(self):
super().__init__()
您可以检查构造函数何时被调用,只需在每个构造函数中(最好在开头)添加一个唯一的打印语句(例如 print(1)、print(2) 等)。
推荐阅读
- python - 使用 VNC 查看器时,模块 screeninfo 无法捕获屏幕分辨率
- html - 如何在 Bootsrap 5 中将行向右移动?
- post - SIM800L GPRS模块与ESP32接口如何自动选择APN
- javascript - 试图将数据表的顶部搜索与 div 的滚动条一起移动
- react-native - 反应原生 Firebase 消息:发布到 Google Play 商店后未收到推送通知
- awk - 使用 awk 替换和添加文本
- c++ - 编译的 ncnn 库未在 Windows 10 代码块 mingw64 上链接
- php - 如何从 php 连接到 PostgreSQL 数据库?
- java - java.lang.reflect.InaccessibleObjectException:无法使字段私有最终瞬态 java.net.InetSocketAddress
- android - Android 11 媒体播放器不工作,Android SDK 30