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 dict
s ,因为它隐藏了实际的签名。
一个解决方案可能是这样的:
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 个 x
s,如果你需要索引功能,你可以使用 list
,否则 set
(甚至 frozenset
强制只执行此分组在初始化时)。
重点是有一个聪明的解决方案可以做你想做的事,但在这里使用结构来聚合你的数据自然会摆脱重复。这个结构将有一个名字,你只需将这个参数传递给 super().__init__
。
关于python - 将参数传递给 super().__init__ 同时将参数保留在签名中的优雅方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63817661/