super().__init__ 覆盖一个属性

super().__init__ overwrites an attribute

我正在子类初始化程序中设置一个属性,它似乎被对 super().__init__ 的调用覆盖了。

from keras.layers import GRU, wrappers


class Dummy(wrappers.Wrapper):
    def __init__(self, layer, **kwargs):
        self.stateful = True
        print(self.stateful)
        super().__init__(layer, **kwargs)
        print(self.stateful)

In [3]: dummy = Dummy(GRU(64, stateful=True))
True
False
In [4]: dummy.stateful
Out[4]: False

我会假设 wrappers.Wrapper 中的某些内容覆盖了属性,但是内置包装器子类 Bidirectional 具有几乎相同的超类 init 调用(我在我的实现中基本上遵循了这个子类的模式)

class Bidirectional(Wrapper):

    def __init__(self, layer, merge_mode='concat', weights=None, **kwargs):
        ...
        self.stateful = layer.stateful
        ...
        super(Bidirectional, self).__init__(layer, **kwargs)

没有表现出这种行为

In [6]: bidir = wrappers.Bidirectional(GRU(64, stateful=True))

In [7]: bidir.stateful
Out[7]: True

我无法解决这个问题。我在 Python 3.6.

下使用 Keras 2.1.3

P.S.

我已经尝试在我的子类中用 super(Dummy, self).__init__(layer, **kwargs) 替换 super().__init__(layer, **kwargs) 但无济于事。

您正在查看 Bidirectional 源代码的错误版本。您查看的版本似乎是 this one,三天前的版本。我相信该版本具有与您的代码相同的错误。

我认为 latest release 中的代码在它自己的 start 调用 super().__init__ __init__:

def __init__(self, layer, merge_mode='concat', weights=None, **kwargs):
    super(Bidirectional, self).__init__(layer, **kwargs)
    ...

这样,它的动作发生在祖先构造函数的动作之后,并且它的 self.stateful 赋值会覆盖它的祖先。