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

Skl*_*vit 7 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)
Run Code Online (Sandbox Code Playgroud)

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

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)
Run Code Online (Sandbox Code Playgroud)

在我看来,代码过于复杂.这种情况有什么指导方针吗?

Mar*_*ers 11

__init__不是构造函数.它是一个初始化方法,为您构造实例之后调用(调用实际的构造方法__new__()).

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

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
Run Code Online (Sandbox Code Playgroud)

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

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


bru*_*ers 5

除了 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"))
Run Code Online (Sandbox Code Playgroud)