【问题标题】:Effects of calling __init__() from inside the object从对象内部调用 __init__() 的效果
【发布时间】:2013-11-19 13:28:42
【问题描述】:

我有时想“重置”一门课程。与其手动清除类中的所有变量及其使用的所有模块,我认为通过调用自身的 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)

这会导致问题,还是有更好的方法来解决这个问题?

【问题讨论】:

    标签: python constructor garbage-collection reset init


    【解决方案1】:

    我建议反其道而行之:

    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。
    • @PlatinumAzure super() 不一定返回直接父级,如果其他东西具有多重继承。例如。如果CAB 的子类,每个子类对象,C 的MRO 可能是C-A-B-object 在这种情况下,A 的__init__ 中的super() 将返回B,即使@ 987654334@ 只是object 的子类。经验法则是总是调用super()的init,如果你要覆盖init。
    • 哦,是的,我忘记了。我的错。我会删除我的评论。
    • @PlatinumAzure 最好将其作为其他人的上下文,但我想现在为时已晚。 :)
    • 顺便说一句,pylint 正在发出警告:Attribute 'small_class' defined outside __init__ (attribute-defined-outside-init)。在__init__ 中有self.small_class = None,并在reset 中实例化它会更好吗?
    【解决方案2】:

    这样做很安全,__init__ 除了自动调用之外没有什么神奇之处。

    但是,正常的做法是将通用代码重构到您的 reset_class 方法中(我称之为 reset 顺便说一句,类已经在类名中)。那么只需从__init__ 方法调用reset

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多