Я прихожу в Python из Scala, где для заданного (case) класса я могу выполнить копию, и на этом же шаге указать произвольное подмножество полей. В Scala это выглядит так:
case class Foo(year: Int, album: String)
// here's a Foo
val foo: Foo = Foo(1973, "Larks Tongues In Aspic")
// updated album with (shallow) copy of year in one step
val nooFoo: Foo = foo.copy(album = "Black Beauty: Live at the Fillmore West")
(пример прост для репликации)
Я видел много вопросов о стеке о копировании неизменяемых данных, но не об их обновлении,Я хотел бы иметь специальный структурный обмен в контексте неизменных обновлений.
Я рассмотрел использование namedtuple
или повышение ошибок в __setattr__
для создания неизменяемого объекта. Тогда, я думаю, у меня могут быть методы, которые вызывают object.__setattr__
, что, похоже, перегружает локальный метод __setattr__
. Но значит ли это, что мне нужно реализовать метод для каждой комбинации обновлений, которые я могу выполнить? Это значит, что мне нужно определить до n! обновить функции для n полей (в теории). В случае класса с 2 полями это может выглядеть следующим образом:
import copy
class Foo:
self.year = None
self.album = None
def __init__(self, year, album):
object.__setattr__(self, "year", year)
object.__setattr__(self, "album", album)
def __setattr__(self):
raise TypeError("i pity the Foo")
def update_a(self, new_year):
noo_foo = copy.copy(self)
object.__setattr__(noo_foo, "year", new_year)
return noo_foo
def update_b(self, new_album):
noo_foo = copy.copy(self)
object.__setattr__(noo_foo, "album", new_album)
return noo_foo
Как Pythonic может выполнять неизменяемые обновления объектов (копии с модификацией полей), не оказываясь в ловушке при записи тонныклассный образец? Или я упускаю что-то простое?