У меня есть экземпляр класса контейнера, который служит основой для нескольких других экземпляров.в примере это называется data0
.я хотел бы иметь возможность сделать копии этого и затем обновить некоторые из членов копий.
да, это можно сделать с помощью модуля copy
, создав копию и назначив новые значения дляучастники.но что, если контейнерный класс является неизменным?
Я надеялся, что смогу реализовать то, что необходимо, чтобы превратить класс в отображение (keys
и __getitem__
) и заставить __init__
принять базукласс плюс некоторые модификации.Вероятно, это было связано с тем, как вы можете обновить словарь:
x = {'a': 0, 'b': 1, 'c': 2}
y = {'b': 7}
z = {**x, 'b': 7}
print(z) # {'a': 0, 'b': 7, 'c': 2}
, поэтому я хотел бы сделать следующее:
data3 = Container(**data0, b=7)
print(data3)
вот что я попробовал:
class Container:
KEYS = ('a', 'b', 'c')
def __init__(self, a=None, b=None, c=None):
self._a = a
self._b = b
self._c = c
@property
def a(self):
return self._a
@property
def b(self):
return self._b
@property
def c(self):
return self._c
def keys(self):
return Container.KEYS
def __getitem__(self, key):
if key not in Container.KEYS:
raise KeyError(key)
return getattr(self, key)
def __str__(self):
return f'{self.__class__.__name__}(a={self.a}, b={self.b}, c={self.c})'
data0 = Container(a=1, b=2, c=3)
print(data0) # Container(a=1, b=2, c=3)
data1 = Container(**data0) # 'copy constructor'
print(data1) # Container(a=1, b=2, c=3)
data2 = Container(**{**data0, 'b':7})
print(data2) # Container(a=1, b=7, c=3)
последний метод работает, но уродлив ...
как указано выше: я хотел бы иметь возможность сделать следующее:
data3 = Container(**data0, b=7)
print(data3)
но это (понятно) завершается ошибкой с сообщением об ошибке
TypeError: объект типа получил несколько значений для ключевого аргумента 'b'
как я могу это исправить?или есть более очевидный способ создания нового экземпляра из заданной базы с обновленными членами?
или это стандартный способ просто наследовать от этого класса с желаемыми значениями по умолчанию?
class Container1(Container):
def __init__(self, a=1, b=2, c=3):
super().__init__(a=a, b=b, c=c)
data3 = Container1(b=7)
print(data3) # Container1(a=1, b=7, c=3)
это немного многословно и имеет недостаток в том, что data3
имеет тип Container1
...
моя попытка на Python 3.5 ведет себя иначе, чем на Python3,6 как описано / спросили здесь .