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

发布于 2025-01-27 05:09:13 字数 491 浏览 5 评论 0原文

我有一个接受很多参数的类,在初始化方法中,我将它们加载到不同命名的参数中。我知道这可能是一个糟糕的设计,但我现在无法改变。我尝试了很多东西,但实际上没有做任何事情。是否可以在数据类别中进行?

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

我知道这不是Dataclass的意图行为,但我想知道是否可以进行一些解决方法。

我想拥有的是Dataclass中的映射:

@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"))

I have a class that accepts a lot of params, and in init method I'm loading them in differently named params. I know it might be a bad design or whatever, but I can't change that right now. I've tried a lot of stuff but nothing really did the thing. Is it possible to do it within dataclasses?

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

I know that this is not intended behaviour of dataclass but I'm wondering if it's possible to make some workaround.

What I'd like to have is this mapping within dataclass:

@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"))

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

街角迷惘 2025-02-03 05:09:13

您可以使用 a>对于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")

You could use an InitVar for the vp alias.

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")

If you need to define many aliases, you could also write your own decorator that uses Field.metadata like so:

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")
单身情人 2025-02-03 05:09:13

这可以工作吗?

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)

Would this work?

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)
画▽骨i 2025-02-03 05:09:13

我看不到这将是一个好主意的任何上下文,但是您可以这样做:

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')

I don't see any context where this would be a good idea, but you can do it in this way:

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')

Which will return:

MyClass(viewport='hola')
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文