可以__init__用作初始化的常规方法,而不是构造函数?

时间:2016-11-14 11:58:14

标签: python design-patterns initialization pep8

有时使用__init__作为现有对象的初始化方法看起来是合理的,即:

class A():
    def __init__(self, x):
        self.x = x

    def set_state_from_file(self, file):
        x = parse_file(file)
        self.__init__(x)

作为此实现的替代方案,我看到以下内容:

class A():
    def __init__(self, x):
        self.init(x)        

    def init(self, x):
        self.x = x

    def set_state_from_file(self, file):
        x = parse_file(file)
        self.init(x)

在我看来,代码过于复杂。这种情况有没有指导方针?

3 个答案:

答案 0 :(得分:11)

__init__不是构造函数。它是一个初始化方法,在实例已经为你构建之后被称为(实际的构造方法被称为__new__())。

如果您需要重新初始化,可以随时从代码中再次调用它,这不是样式违规。实际上,它用在Python标准库中;例如,请参阅multiprocessing.heap.Heap() implementation

def malloc(self, size):
    # return a block of right size (possibly rounded up)
    assert 0 <= size < sys.maxsize
    if os.getpid() != self._lastpid:
        self.__init__()                     # reinitialize after fork

threading.local implementation,它使用上下文管理器来推迟初始化。

__init__方法本身没有什么特别之处。它仅由type.__call__自动调用(在使用instance = cls.__new__(cls, *args, **kwargs)创建实例后,如果可用则调用cls.__init__(instance, *args, **kwargs)。)

答案 1 :(得分:4)

除了Martjin的回答:Python中的一个常见模式是使用classmethods作为工厂方法,即:

class A():
    def __init__(self, x):
        self.x = x

    @classmethod
    def from_file(cls, file):
        x = parse_file(file)
        return cls(x)


a1 = A(42)
a2 = A.from_file(open("/path/to/file"))

答案 2 :(得分:0)

我发现__init__和&#39;正常&#39;之间存在一些差异方法:

1。,__init__不允许返回任何内容:将引发TypeError。

2.如果__init__引发错误,将调用__del__: Martijn Pieters的更新:这仅适用于构造函数调用,不适用于通用用法,请参阅下面的注释。

 class A(object):
     def __init__(self):
           print('__init__')
           raise ValueError('__init__ error')
           pass

    def method(self):
        raise ValueError('method error')

    def __del__(self):
        print("__del__")

def main():
    try:
        a = A()
        a.method()
    except ValueError as e:
        print(e)
    print('exit main')

if __name__ == '__main__':
    main()
    print('end of file')

将输出:

__init__
__init__ error
__del__
exit main
end of file