有时使用__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)
在我看来,代码过于复杂。这种情况有没有指导方针?
答案 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