【问题标题】:How can I get a modified copy of a immutable object?如何获得不可变对象的修改副本?
【发布时间】:2020-09-16 19:55:42
【问题描述】:

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

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


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

      这是一种可以满足您的需求的方法!将其添加到您的对象中,这是我的代码和输出:

      @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-12-30
        • 1970-01-01
        • 2020-11-19
        • 2022-01-07
        • 1970-01-01
        相关资源
        最近更新 更多