属性库和超级

attrs library and super

这是我要重构的 class 的玩具示例。实际上我更喜欢parameters/attributes动量,所以代码重复很多:

class TransformBl(tf.keras.Model):
    def __init__(self, 
                 features,
                 momentum=0.1,
                 **kwargs):        
        super(TransformBl, self).__init__(**kwargs)
        self.features = features
        self.momentum = momentum
        self.transform = tf.keras.layers.Dense(self.features, use_bias=False)

    def call(self, inputs, training=None):
        x = self.transform(inputs)
        return x

我已经开始寻找避免重复的解决方案,attrs 库似乎适合。 featuresmomentum和继承都没有问题。 不幸的是,我在 __init__ 中找不到 super(TransformBl, self).__init__(**kwargs) 这样的构造示例 我试过 super() 但我得到了 RuntimeError: super(): no arguments

有没有办法用 attrs 风格重写这个 class?

更新:

attrs 21.1.0 开始,添加了对 __attrs_pre_init____attrs_init__ 的支持。详情请见the docs on initialization

对于早于 21.1.0 的 attrs 版本,旧答案仍然适用:

恐怕您既不能使用 attrs 也不能使用数据类,因为某些难以理解的原因而被提及。既不允许您的 __init__ 使用 **kwargs 但更重要的是,在设置该实例的属性之前都不允许您使用 运行 super().__init__() 因为两者都只有 [=42] 的概念=]post-init hook.

尝试使用它会给你一个运行时错误,因为模型拦截 __setattr__:

RuntimeError: It looks like you are subclassing `Model` and you forgot to call `super(YourClass, self).__init__()`. Always start with this line.

attrs 可以通过编写一个单独的 __attrs_init__ 方法来增加对你想要的东西的支持,你可以从你的 __init__ 调用你自己,在 运行 必要的超级之后: https://github.com/python-attrs/attrs/issues/393

没有迫在眉睫的时间表,但像这样的问题是一个很好的例子。

在链接的票证中,还有一个 elaborate workaround 解决了 PyTorch 的类似问题。