类继承,其中子级是简单的仅变量类

问题描述 投票:0回答:1

我正在使用一些 YAML 补丁。这些补丁具有相似的结构,但包含不同的值。这些值通常很难记住,所以我想将它们抽象成我可以引用的类实例。

这是我迄今为止采取的方法:

class YamlPatch:
    def __init__(self, kind, name, namespace, op, path, value):
        target={
            "kind": kind,
            "name": name,
            "namespace": namespace
        },
        scalar=[{
            "op": op,
            "path": path,
            "value": value
        }]

        self.yaml = (target, scalar)

class PatchA(YamlPatch):
    def __init__(self, name):
        namespace = "my-namespace"
        kind = "test"
        op = "replace"
        path = "/test"
        value = "hello"

        super().__init__(kind, name, namespace, op, path, value)

class PatchB(YamlPatch):
    def __init__(self, path):
        namespace = "my-namespace"
        name = "my-name"
        kind = "test"
        op = "replace"
        value = "hello"

        super().__init__(kind, name, namespace, op, path, value)

### Insert 4 or 5 other types of patches here...

patches = []
patches.append(PatchA("hello").yaml)
for app in ["app1", "app2"]:
    patches.append(PatchB(f"/{app}").yaml)

print(patches)

### output: [(({'kind': 'test', 'name': 'hello', 'namespace': 'my-namespace'},), [{'op': 'replace', 'path': '/test', 'value': 'hello'}]), (({'kind': 'test', 'name': 'my-name', 'namespace': 'my-namespace'},), [{'op': 'r
eplace', 'path': '/app1', 'value': 'hello'}]), (({'kind': 'test', 'name': 'my-name', 'namespace': 'my-namespace'},), [{'op': 'replace', 'path': '/app2', 'value': 'hello'}])]

这感觉很混乱和重复,尤其是当您添加类型提示和注释时。不是很干。有些值是相当常见的默认值,并且必须在每个子类(补丁)中先

__init__
然后
super()
感觉不太好。

我尝试使用数据类,但由于子类所需的“输入”参数不同,我必须使用

kw_only
参数,这可能很难记住这么多不同的补丁(例如
PatchA(value="blah")
或它是
PatchA(name="blah")
,我不记得了?)。

简而言之,我正在寻找最快、最有效的方式来编写代码,这样我就可以引用一个容易记住、简单的名称(我在这里将它们称为

PatchA
PatchB
,但在实际代码中,它们将是对维护者来说是独特且明显的)并返回格式正确的 YAML 补丁。例如。
print(PatchA)

我正在使用Python 3.11。

python python-3.x
1个回答
0
投票

您可以使用

dataclass
并消除子类。

from dataclasses import dataclass


@dataclass
class YamlPatch:
  namespace :str = "my-namespace"
  kind      :str = "test"
  name      :str = "my-name"
  op        :str = "replace"
  path      :str = "/test"
  value     :str = "hello"

  def __post_init__(self) -> None:
    target={
      "namespace": self.namespace ,
      "kind"     : self.kind      ,
      "name"     : self.name      ,
    }
    
    scalar=[{
      "op"   : self.op    ,
      "path" : self.path  ,
      "value": self.value ,
    }]
    
    self.yaml = (target, scalar)
    
  def __str__(self) -> str:
    return str(self.yaml)


if __name__ == "__main__":
  
  patches = [YamlPatch(name="hello").yaml]
  
  for app in ["app1", "app2"]:
      patches.append(YamlPatch(path=f"/{app}").yaml)
  
  print(*patches, sep='\n')
© www.soinside.com 2019 - 2024. All rights reserved.