我正在使用一些 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。
您可以使用
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')