【发布时间】:2018-05-12 12:03:29
【问题描述】:
考虑以下示例 sn-p
import abc
class BASE(metaclass=abc.ABCMeta):
def __init__(self, name):
assert name is not None, "Name must be provided."
self.num = 3
@abc.abstractmethod
def compute(self):
pass
class CHILD(BASE):
def __init__(name):
'''
'''
def compute(self):
return self.num + 34
在执行时会出现以下错误:
AttributeError: 'CHILD' 对象没有属性 'num'
在目前的情况下,BASE 没有被初始化,因为如果我们如下添加一个打印函数,它绝对不会打印任何东西。
class BASE(metaclass=abc.ABCMeta):
def __init__(self, name):
print(name)
assert name is not None, "Name must be provided."
self.num = 3
我们可以在这个类设计中做些什么来确保从BASE 子类化的实现器必须显式调用BASE 的初始化程序吗?
【问题讨论】:
-
只确保定义了
self.num就足够了吗?如果是这样,@abstractproperty装饰器可以解决问题……或者堆叠@abstractmethod和@property(Python 3.3+)。更多详情:stackoverflow.com/questions/5960337/… -
。嗯。在这种情况下,是的,这就足够了。但我正在考虑更复杂和更大规模的项目,例如,父类可能会用于初始化一些数据库或进行一些身份验证或做一些其他不平凡的工作。在这种情况下,强制的显式初始化会很重要(或者我认为)。
-
我明白了……这必须在子类的实例被实例化时发生?也就是说,不是在子类本身创建的时候?
-
我认为,如果您通过设计推测,由子类编写者来确保他们调用 super。
-
+1 @kyle 的评论 - 在 Python 中,通常假设我们都是同意的成年人。这意味着,如果您正确记录了您的基类以及它应该如何被子类化(包括调用它的
__init__()方法),那么假设使用它的成年人会阅读文档并尊重它的期望并不是不合理的。
标签: python python-3.x