【发布时间】:2020-02-18 23:05:03
【问题描述】:
我有一个根级 config 类,我通过依赖注入将其传递到我的代码库中。
问题是,我有这个数据类需要这个配置中的一些属性来计算 __post_init__() 中的值 world_coords。
为了保持我的测试干净并规避其他测试导入问题(此处未讨论),我希望能够将配置直接传递给该对象,而不是从导入中读取这些值。但是,如果我将配置构造为参数,它就会成为数据类的一个属性,这是我试图避免的。 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))
如何将配置传递给数据类进行初始化而不使其成为数据类的属性?我是否应该为这个用例考虑一个数据类?我相信最初的意图是保持所有实例不可变,但我无法确认。
【问题讨论】:
-
不将
config定义为init-only variable 解决您的问题吗? -
@Tupteq 这看起来正是我所需要的!我在文档中完全错过了这一点。回到电脑前,我将需要对其进行测试。
-
@Tupteq 完美运行。如果您将其作为问题的官方答案,我可以接受。
-
很高兴我能帮上忙。我会回答的。
标签: python python-3.x python-dataclasses