如何获得一个不可变对象的修改副本?

问题描述 投票:0回答:2

如何获得一个不可变对象的修改副本?

即如何才能 some_magical_method 看起来像这个片段?

import attr

@attr.s(frozen=True, slots=True)
class Config:
    param1: int = attr.ib()
    param2: str = attr.ib()

my_base_config = Config(param1=1, param2="2")
my_derived_config = my_base_config.some_magical_method(param2="two")

print(my_derived_config.param1) # output: 1
print(my_derived_config.param2) # output: two

背景:我想在我的配置中使用不可变的对象。我想在配置中使用不可变的对象。但我也希望在处理非常相似的配置时避免代码重复,例如单元测试时。

python-3.x immutability copy-constructor python-3.8 python-attrs
2个回答
1
投票

attrs 有一个专门为你准备的函数。https:/www.attrs.orgenstableapi.html#attr.evolve

由于它把实例作为第一个参数,你也可以用它来定义一个方法。

@attr.s
class C:
    some_magical_method = attr.evolve

1
投票

这里有一个方法可以做你想要的事情!把它添加到你的对象中,这是我的代码和输出。

@attr.s(frozen=True, slots=True)
class Config:
    param1: int = attr.ib()
    param2: str = attr.ib()

    def some_magical_method(self, **kwargs):
        params_to_use = {"param1": self.param1, "param2": self.param2}
        params_to_use.update(kwargs)
        new_obj = Config(**params_to_use)
        return new_obj

my_base_config = Config(param1=1, param2="2")
my_derived_config = my_base_config.some_magical_method(param2="two")

>>> print(my_derived_config.param1) # output: 1
1
>>>print(my_derived_config.param2) # output: two
two

这里的关键是该方法创建了新的Config对象, 首先使用它自己的值, 然后用任何传入该方法的值覆盖... params_to_use.update(kwargs). 然后将更新后的值传递给新对象的constructorinit,并返回。

希望对大家有所帮助,祝大家编码愉快!

© www.soinside.com 2019 - 2024. All rights reserved.