将帮助器变量传递给dataclass _init _;而不分配它们

2024-06-07 12:19:42 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个根级别的config类,我通过依赖项注入在代码库中传递它

问题是,我有一个dataclass,它需要这个配置中的一些属性来计算__post_init__()中的值world_coords

为了保持我的测试干净并避免其他测试导入问题(这里没有讨论),我希望能够将配置直接传递给这个对象,而不是从导入中读取这些值。但是,如果我将配置构造为参数,它将成为dataclass的一个属性,这是我试图避免的。一旦使用了配置,就不需要RoadSegmentNode来保持对配置的引用

以下是该课程的基本结构:

@dataclass(eq=True, frozen=True)  # make hashable
class RoadSegmentNode:

    tile_index: Tuple[int, int]  # (r, c)
    dir: Direction
    node_type: RoadNodeType
    world_coords: Tuple[int, int] = field(init=False)

    def __post_init__(self):

        # (Use config variables here, e.g. `config.TILE_WIDTH`, to calculate x and y)

        # Hack to get around frozen=True. We don't care that we're mutating
        # an "immutable" object on __init__().
        object.__setattr__(self, "world_coords", (x, y))

下面是我使用依赖注入模型的权宜之计,以暂时解除对测试的阻碍。请注意RoadSegmentNode现在有一堆只用于初始化的新属性。这比保留对配置的引用要好一点,因为至少它们是显式的,但它仍然是一个非常糟糕的设计

@dataclass(eq=True, frozen=True)  # make hashable
class RoadSegmentNode:

    # NOTE: DO NOT ACCESS THESE ATTRIBUTES!
    grid_width: int
    grid_height: int
    tile_width: int
    tile_height: int
    road_width: int

    tile_index: Tuple[int, int]  # (r, c)
    dir: Direction
    node_type: RoadNodeType
    world_coords: Tuple[int, int] = field(init=False)

    def __post_init__(self):

        # (Use attributes here, e.g. `self.tile_width`, to calculate x and y)

        # Hack to get around frozen=True. We don't care that we're mutating
        # an "immutable" object on __init__().
        object.__setattr__(self, "world_coords", (x, y))

如何将配置传递给dataclass进行初始化,而不使其成为dataclass的属性?我是否应该为这个用例考虑一个数据类?我相信最初的意图是保持所有实例不变,但我不能证实


Tags: toselftrueworld属性objectinitcoords
1条回答
网友
1楼 · 发布于 2024-06-07 12:19:42

您应该将config定义为init-only variable。通过这种方式,它将被传递到__post_init__(),但随后将消失:

from dataclass import dataclass, field
from typing import InitVar

@dataclass(eq=True, frozen=True)
class RoadSegmentNode:

    tile_index: Tuple[int, int]
    dir: Direction
    node_type: RoadNodeType
    world_coords: Tuple[int, int] = field(init=False)
    config: InitVar[Config]  # will not appear in instances


    def __post_init__(self, config):
        x, y = ..., ...  # calculate using config

        # looks hacky for sure, but is the right way to work with frozen dataclasses
        object.__setattr__(self, "world_coords", (x, y))

相关问题 更多 >

    热门问题