在Python数据类中向嵌套属性传递值

r1zhe5dt  于 2023-06-28  发布在  Python
关注(0)|答案(2)|浏览(118)

我试图创建一个具有嵌套属性的python数据类的示例,当我传递一个属于某个嵌套属性的属性时,它应该用提供的值替换实际值。这里我尝试:

from dataclasses import dataclass, field
from typing import Optional

@dataclass(kw_only=True)
class Attributes:
    correlation_id: Optional[str] = None
    routing_key: Optional[str] = None

@dataclass(kw_only=True)
class Metadata:
    workflow: Optional[str] = None
    workflow_state_id: Optional[str] = None
    attributes: Optional[Attributes] = field(default=None)

    def __post_init__(self):
        if self.attributes is None:
            self.attributes = Attributes()

@dataclass(kw_only=True)
class Message:
    version: Optional[int] = field(default=0)
    metadata: Optional[Metadata] = field(default=None)

    def __post_init__(self):
        if self.metadata is None:
            self.metadata = Metadata()

@dataclass(kw_only=True)
class Command(Message):
    ...

@dataclass(kw_only=True)
class SomeCommand(Command):
    name: str
    description: str

c1 = SomeCommand(name="awesome command", description="desc", routing_key='some key')
print(c1)

我的预期React应该是:

SomeCommand(version=0, metadata=Metadata(workflow=None, workflow_state_id=None, attributes=Atributes(correlation_id=None, routing_key='some key')), name='awesome command', description='desc')

但它不工作,并显示错误:

TypeError: SomeCommand.__init__() got an unexpected keyword argument 'routing_key'

在Python数据类中可以做什么?如果是,我应该改变什么?先谢谢你了。

4szc88ey

4szc88ey1#

这并不是数据类的设计使用方式。
您可以使用以下命令强制Message沿着参数传递给Metadata,并强制Metadata将参数传递给Atributes

from dataclasses import InitVar

@dataclass(kw_only=True)
class Metadata:
    workflow: Optional[str] = None
    workflow_state_id: Optional[str] = None
    attributes: Optional[Atributes] = field(default=None)
    correlation_id: InitVar[Optional[str]] = None
    routing_key: InitVar[Optional[str]] = None

    def __post_init__(self, correlation_id, routing_key):
        if self.attributes is None:
            self.attributes = Atributes(correlation_id=correlation_id, routing_key=routing_key)

@dataclass(kw_only=True)
class Message:
    version: Optional[int] = field(default=0)
    metadata: Optional[Metadata] = field(default=None)
    correlation_id: InitVar[Optional[str]] = None
    routing_key: InitVar[Optional[str]] = None

    def __post_init__(self, correlation_id, routing_key):
        if self.metadata is None:
            self.metadata = Metadata(correlation_id=correlation_id, routing_key=routing_key)

但我觉得这有点难看。
(Is Atribute拼写错误,而self.attributes拼写正确?)

kgsdhlau

kgsdhlau2#

如果你想做一个复杂的初始化,你可以在你的构造函数中使用一个字典,比如**kwargs。初始化如下:

c1 = SomeCommand(**{
  "name": "awesome command",
  "description": "desc",
  "metadata": Metadata(**{
      "attributes": Atributes(**{
          "routing_key": "some key"
      })
  })
})

相关问题