python - 将参数传递给 super().__init__ 同时将参数保留在签名中的优雅方法?

标签 python

class A:
    def __init__(self, x1, x2, x3, x4):
        pass
        ...

class B(A):
    def __init__(self, x1, x2, x3, x4, y1, y2):
        super().__init__(x1, x2, x3, x4)  # How to replace this without repeating the argument names?
        ...

我不想use **kwargs or dicts ,因为它隐藏了实际的签名。

一个解决方案可能是这样的:

from inspect import signature

class B(A):
    def __init__(self, x1, x2, x3, x4, y1, y2):
        sig = signature(super().__init__)
        params = {k: v for k, v in locals().items() if k in sig.parameters}
        super().__init__(**params)
        ...

但这很麻烦并且有其自身的问题。有什么可以做的更优雅的事情吗?

编辑:这个问题的动机是 DRY 原则。

最佳答案

扩展我的评论:

这听起来像 x1、x2、x3、x4 在逻辑上是分组的,因为您会看到它们的名称在整个类层次结构中重复出现。您可以使用 tuple 来消除重复。一个更好的解决方案是 @dataclass ,如果逻辑分组在初始化时建立,最好是只读的,之后不应更改。这两种解决方案都支持异构类型。

from dataclasses import dataclass

@dataclass(frozen=True)
class X:
    x1: ...
    x2: ...
    x3: ...
    x4: ...

请注意,您不需要在此处使用@dataclass,实际上任何具有__init__ 方法的类都可以聚合此数据,并且将它分配给 self 属性会起作用。但是 @dataclass 在这里提供了一些漂亮的功能,请参阅链接和评论。

如果 x1 ... x4 的类型是同质的,并且您不需要特别强制其中有 4 个 xs,如果你需要索引功能,你可以使用 list,否则 set(甚至 frozenset 强制只执行此分组在初始化时)。

重点是有一个聪明的解决方案可以做你想做的事,但在这里使用结构来聚合你的数据自然会摆脱重复。这个结构将有一个名字,你只需将这个参数传递给 super().__init__

关于python - 将参数传递给 super().__init__ 同时将参数保留在签名中的优雅方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63817661/

相关文章:

python - matplotlib: xaxis dates ValueError: format %y requires year >= 1900 on Windows

Python Django 多处理错误 : "AttributeError: Can' t pickle local object 'Command.handle.<locals>.f' "

python - 将数据分配给 for 循环中的现有列

python - 为什么当 PyPi 显示版本 1.0.0 时 pip 安装 matplotlib 版本 0.91.1?

python - 使用列号中的条件使用 python 和 xlwt 导出到 Excel

python - 使用 matplotlib 简化三角剖分

python - 使用地理位置跟踪主题标签 - tweepy

python - 更新 numpy 数组中的值时修复代码重复

python - “zsh: illegal hardware instruction python” 在 macbook pro M1 上使用 Tensorflow

python - 在 python 2.4 中,如何使用 csh 而不是 bash 执行外部命令?