Как я могу получить измененную копию неизменяемого объекта? - PullRequest
0 голосов
/ 29 мая 2020

Как получить измененную копию неизменяемого объекта?

Т.е. как 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

Справочная информация: я хочу использовать неизменяемые объекты для моей конфигурации. Но я также хочу избежать дублирования кода при работе с очень похожими конфигурациями, например, для модульных тестов

Ответы [ 2 ]

1 голос
/ 29 мая 2020

attrs имеет функцию специально для вас: https://www.attrs.org/en/stable/api.html#attr .evolve

Поскольку он принимает экземпляр в качестве первого аргумента, вы также можете использовать его для определения метода:

@attr.s
class C:
    some_magical_method = attr.evolve
1 голос
/ 29 мая 2020

Вот метод, который делает то, что вы хотите! Добавьте его к своему объекту, вот мой код и результат:

@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). Обновленные значения затем передаются в конструктор / инициализацию нового объекта, который возвращается.

Надеюсь, что это поможет, удачного кодирования!

...