调用 __init__() 函数对对象的影响

3

我有一个类,有时候我想要“重置”它。我认为通过调用init方法来重构它会比手动清空类中所有变量及其使用的模块更好。我的担忧是,我不确定这是否是一个良好的设计模式,或者GC是否正确地清除了旧对象。

以下是一个示例:

from modules import SmallClass
from modules import AnotherClass

class BigClass(object):
    def __init__(self, server=None):
        """construct the big class"""
        self.server = server
        self.small_class = SmallClass(self.server)
        self.another_class = AnotherClass(small_class)

    def reset_class(self):
        """reset the big class"""
        self.__init__(self.server)

这会在后续造成问题吗?还是有更好的方法处理?
2个回答

5

我建议采用另一种方式:

from modules import SmallClass
from modules import AnotherClass

class BigClass(object):
    def __init__(self, server=None):
        """construct the big class"""
        self.reset_class(server)

    def reset_class(self, server=None):
        """reset the big class"""
        self.server = server
        self.small_class = SmallClass(self.server)
        self.another_class = AnotherClass(small_class)

这种模式非常常见,因为它允许__init__重置类,并且您也可以单独重置类。我还在其他面向对象语言(如Java)中看到了这种模式。


顺便提一下,__init__ 也应该调用 super() 的 init。 - Amber
@PlatinumAzure super() 不一定会返回直接父类,如果其他东西具有多重继承。例如,如果 C 子类化了 AB,它们各自子类化对象,则 C 的 MRO 可能是 C-A-B-object,在这种情况下,在 A 的 __init__ 中调用 super() 将返回 B,即使 A 仅是 object 的子类。经验法则是,如果您要覆盖 init,则始终调用 super() 的 init。 - Amber
哦,是的,我忘了那个。我的错误。我会删除我的评论。 - Platinum Azure
@PlatinumAzure 最好让它作为其他人的上下文,但现在我想已经太晚了。 :) - Amber
顺便提一下,pylint正在发出警告:Attribute 'small_class' defined outside __init__ (attribute-defined-outside-init)。在__init__中是否最好有self.small_class = None,并在reset中实例化它? - Jono

2

这是安全的操作,__init__并没有什么神奇之处,除了它会自动调用。

然而,通常做法是将通用代码重构到reset_class方法中(我会将其称为reset,类名已经在类名中了)。然后只需从__init__方法中调用reset即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接