我有两个班,如下所示:
class Super(object):
def __init__(self, arg):
self.arg = arg
def load(self):
# Load data from disk if available
try:
self.data = load_routine()
except IOError as e:
if e[0] == errno.ENOENT:
pass
else:
raise
class Sub(Super):
def __init__(self, arg2, *args, **kwargs):
super(Sub, self).__init__(*args, **kwargs)
self.arg2 = arg2
def load(self):
# Load files specific to superclass
super(Sub, self).load()
# Load data from disk if available
try:
self.data2 = another_different_load_routine(self.arg2)
except IOError as e:
if e[0] == errno.ENOENT:
pass
else:
raise
{I希望这两个类都能很好的使用。在
但是,实际上我希望load方法在__init__()
结束时自动调用,但我不确定如何实现这一点。{{If}将从cd2>的子类的实例中同时调用一次。在
如果我只将对self.load()
的调用放在超类的init方法的末尾,那么它将只被调用一次,但对象还没有初始化为包含加载所需的属性。在
当实例化Sub
时,我希望它初始化__init__
中父类和子类的所有属性,并为父类和子类调用load()
。是否按顺序
Super -> __init__()
,Super -> load()
,Sub -> __init__()
,Sub -> load()
或者
Super -> __init__()
,Sub -> __init__()
,Super -> load()
,Sub -> load()
不重要。我怎样才能做到这一点?在
答案是您未能列举的组合:
如果你真的想实例化super(它不是一个抽象类),你需要在它的init中进行
if
测试。否则,您无法使用当前的类结构和初始化方案获得所需的有序语义。在Sub()
将调用Sub.__init__
,它将调用Super.__init__
(在执行任何操作之前)。在之后,
__init__
上的Sub
将完成它的工作。在最后,
Sub.__init__
将调用Sub.load
,它将调用Super.load
(在做任何事情之前),然后自己做。在“正常”的方法是
^{pr2}$根本没有调用
__init__
方法的load
。如果您真的想调用load
中的级别,这可能是我推荐的,因为它实际上是__init__
的第二组编辑:阅读前两个版本中关于失败的评论(并查看编辑以查看旧版本)。下面是另一个版本,使用元类:
这有一个不同的限制:所有子类都可以正常工作,除了不能通过使用
super().__init__()
调用Sub.__init__
。我认为有可能删除这个限制,但是我不知道在没有另一层间接寻址的情况下如何。在如果您总是希望
__init__()
完全初始化对象,然后调用load()
,那么我将把这两个函数提取到单独的方法中:现在你有一个你没有重写的
__init__()
,你不再把初始化和加载这两个单独的操作混合在一起。在相关问题 更多 >
编程相关推荐