数据类参数是否有别名或名称参数?



我有一个接受很多参数的类,在init方法中我将它们加载到不同命名的参数中。我知道这可能是一个糟糕的设计或其他什么,但我现在不能改变。我试过很多方法,但都没有效果。有可能在数据类中做到这一点吗?

class MyClass:
def __init__(self, vp):
self.viewport = vp

我知道这不是数据类的预期行为,但我想知道是否有可能做出一些解决方案。

我想要的是数据类中的映射:

@dataclass
class MyClass:
viewport:str = "" # this should get the value from vp argument if possible
so when I call:
mc = MyClass(vp="foo")
print(mc) should return (MyClass(viewport="foo"))

这样行吗?

from dataclasses import dataclass

arg_dict = {'vp':'viewport'}
@dataclass
class RealMyClass():
viewport: str = ''
some_other_field: int = 10


class MyClass(RealMyClass):
def __init__(self, **kwargs):
super().__init__(**{arg_dict[arg]:value for arg, value in kwargs.items()})

print(MyClass(vp='foo'))
MyClass(viewport='foo', some_other_field=10)

您可以使用InitVar作为vp别名。

from dataclasses import dataclass, InitVar

@dataclass
class MyClass:
viewport: str = ""  # this should get the value from vp argument if possible
vp: InitVar[str] = None
def __post_init__(self, vp):
if vp:
self.viewport = vp

mc = MyClass(vp="foo")

如果你需要定义许多别名,你也可以编写自己的装饰器,使用Field.metadata,像这样:

from dataclasses import dataclass, field, fields
from functools import wraps

def _wrap_init(original_init):
@wraps(original_init)
def __init__(self, *args, **kwargs):
aliases = {}
for field in fields(self):
alias = field.metadata.get("alias")
if alias is not None:
value = kwargs.pop(alias)
aliases[field.name] = value
original_init(self, *args, **kwargs)
for name, value in aliases.items():
setattr(self, name, value)
return __init__

def aliased(cls):
original_init = cls.__init__
cls.__init__ = _wrap_init(original_init)
return cls

@aliased
@dataclass
class MyClass:
viewport: str = field(default="", metadata={"alias": "vp"})

mc = MyClass(vp="foo")

我不认为这是一个好主意,但你可以这样做:

from dataclasses import dataclass, field, InitVar
@dataclass
class MyClass:
vp: InitVar[str]
viewport: str = field(init=False)
def __post_init__(self,vp):
self.viewport = vp

MyClass(vp='hola')

返回:

MyClass(viewport='hola')

最新更新