0

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

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

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

4

2 回答 2

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). 然后将更新的值传递给返回的新对象的构造函数/init。

希望对您有所帮助,快乐编码!

于 2020-05-29T17:17:30.197 回答
1

attrs有专门为你准备的功能:https ://www.attrs.org/en/stable/api.html#attr.evolve

由于它将实例作为第一个参数,因此您也可以使用它来定义方法:

@attr.s
class C:
    some_magical_method = attr.evolve
于 2020-05-29T20:21:06.603 回答